// This tests that GrTextureStripAtlas flushes pending IO on the texture it acquires. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); GrSurfaceDesc desc; desc.fWidth = 32; desc.fHeight = 32; desc.fConfig = kRGBA_8888_GrPixelConfig; GrTexture* texture = context->textureProvider()->createTexture(desc, SkBudgeted::kYes, nullptr, 0); GrSurfaceDesc targetDesc = desc; targetDesc.fFlags = kRenderTarget_GrSurfaceFlag; GrTexture* target = context->textureProvider()->createTexture(targetDesc, SkBudgeted::kYes, nullptr, 0); SkAutoTMalloc<uint32_t> pixels(desc.fWidth * desc.fHeight); memset(pixels.get(), 0xFF, sizeof(uint32_t) * desc.fWidth * desc.fHeight); texture->writePixels(0, 0, desc.fWidth, desc.fHeight, kRGBA_8888_GrPixelConfig, pixels.get()); // Add a pending read to the texture, and then make it available for reuse. context->copySurface(target, texture); texture->unref(); // Create an atlas with parameters that allow it to reuse the texture. GrTextureStripAtlas::Desc atlasDesc; atlasDesc.fContext = context; atlasDesc.fConfig = desc.fConfig; atlasDesc.fWidth = desc.fWidth; atlasDesc.fHeight = desc.fHeight; atlasDesc.fRowHeight = 1; GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(atlasDesc); // Write to the atlas' texture. SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType); size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig); SkBitmap bitmap; bitmap.allocPixels(info, rowBytes); memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight); int row = atlas->lockRow(bitmap); if (!context->caps()->preferVRAMUseOverFlushes()) REPORTER_ASSERT(reporter, texture == atlas->getTexture()); // The atlas' use of its texture shouldn't change which pixels got copied to the target. SkAutoTMalloc<uint32_t> actualPixels(desc.fWidth * desc.fHeight); bool success = target->readPixels(0, 0, desc.fWidth, desc.fHeight, kRGBA_8888_GrPixelConfig, actualPixels.get()); REPORTER_ASSERT(reporter, success); REPORTER_ASSERT(reporter, !memcmp(pixels.get(), actualPixels.get(), sizeof(uint32_t) * desc.fWidth * desc.fHeight)); target->unref(); atlas->unlockRow(row); }
void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) { GrVkGpu* gpu = static_cast<GrVkGpu*>(context->getGpu()); GrBackendObject backendObj = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kPixelConfig, false); const GrVkImageInfo* backendTex = reinterpret_cast<const GrVkImageInfo*>(backendObj); // check basic borrowed creation GrBackendTextureDesc desc; desc.fConfig = kPixelConfig; desc.fWidth = kW; desc.fHeight = kH; desc.fTextureHandle = backendObj; GrTexture* tex = gpu->wrapBackendTexture(desc, kBorrow_GrWrapOwnership); REPORTER_ASSERT(reporter, tex); tex->unref(); // image is null GrVkImageInfo backendCopy = *backendTex; backendCopy.fImage = VK_NULL_HANDLE; desc.fTextureHandle = (GrBackendObject) &backendCopy; tex = gpu->wrapBackendTexture(desc, kBorrow_GrWrapOwnership); REPORTER_ASSERT(reporter, !tex); tex = gpu->wrapBackendTexture(desc, kAdopt_GrWrapOwnership); REPORTER_ASSERT(reporter, !tex); // alloc is null backendCopy.fImage = backendTex->fImage; backendCopy.fAlloc = { VK_NULL_HANDLE, 0, 0 }; tex = gpu->wrapBackendTexture(desc, kBorrow_GrWrapOwnership); REPORTER_ASSERT(reporter, !tex); tex = gpu->wrapBackendTexture(desc, kAdopt_GrWrapOwnership); REPORTER_ASSERT(reporter, !tex); // check adopt creation backendCopy.fAlloc = backendTex->fAlloc; tex = gpu->wrapBackendTexture(desc, kAdopt_GrWrapOwnership); REPORTER_ASSERT(reporter, tex); tex->unref(); gpu->deleteTestingOnlyBackendTexture(backendObj, true); }
GrTexture* GrGpu::createPlatformTexture(const GrPlatformTextureDesc& desc) { this->handleDirtyContext(); GrTexture* tex = this->onCreatePlatformTexture(desc); // TODO: defer this and attach dynamically GrRenderTarget* tgt = tex->asRenderTarget(); if (NULL != tgt && !this->attachStencilBufferToRenderTarget(tgt)) { tex->unref(); return NULL; } else { return tex; } }
GrTexture* GrGpu::wrapBackendTexture(const GrBackendTextureDesc& desc, GrWrapOwnership ownership) { this->handleDirtyContext(); GrTexture* tex = this->onWrapBackendTexture(desc, ownership); if (NULL == tex) { return NULL; } // TODO: defer this and attach dynamically GrRenderTarget* tgt = tex->asRenderTarget(); if (tgt && !this->attachStencilAttachmentToRenderTarget(tgt)) { tex->unref(); return NULL; } else { return tex; } }
GrTexture* GrGpu::createTexture(const GrTextureDesc& desc, const void* srcData, size_t rowBytes) { this->handleDirtyContext(); GrTexture* tex = this->onCreateTexture(desc, srcData, rowBytes); if (NULL != tex && (kRenderTarget_GrTextureFlagBit & desc.fFlags) && !(kNoStencil_GrTextureFlagBit & desc.fFlags)) { GrAssert(NULL != tex->asRenderTarget()); // TODO: defer this and attach dynamically if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) { tex->unref(); return NULL; } } return tex; }
GrTexture* GrGpu::wrapBackendTexture(const GrBackendTextureDesc& desc, GrWrapOwnership ownership) { this->handleDirtyContext(); if (!this->caps()->isConfigTexturable(desc.fConfig)) { return nullptr; } if ((desc.fFlags & kRenderTarget_GrBackendTextureFlag) && !this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { return nullptr; } GrTexture* tex = this->onWrapBackendTexture(desc, ownership); if (nullptr == tex) { return nullptr; } // TODO: defer this and attach dynamically GrRenderTarget* tgt = tex->asRenderTarget(); if (tgt && !fContext->resourceProvider()->attachStencilAttachment(tgt)) { tex->unref(); return nullptr; } else { return tex; } }
GrTexture* GrGpu::createTexture(const GrTextureDesc& desc, const void* srcData, size_t rowBytes) { if (!this->caps()->isConfigTexturable(desc.fConfig)) { return NULL; } if ((desc.fFlags & kRenderTarget_GrTextureFlagBit) && !this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { return NULL; } GrTexture *tex = NULL; if (GrPixelConfigIsCompressed(desc.fConfig)) { // We shouldn't be rendering into this SkASSERT((desc.fFlags & kRenderTarget_GrTextureFlagBit) == 0); if (!this->caps()->npotTextureTileSupport() && (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight))) { return NULL; } this->handleDirtyContext(); tex = this->onCreateCompressedTexture(desc, srcData); } else { this->handleDirtyContext(); tex = this->onCreateTexture(desc, srcData, rowBytes); if (tex && (kRenderTarget_GrTextureFlagBit & desc.fFlags) && !(kNoStencil_GrTextureFlagBit & desc.fFlags)) { SkASSERT(tex->asRenderTarget()); // TODO: defer this and attach dynamically if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) { tex->unref(); return NULL; } } } return tex; }
GrTexture* GrGpu::createTexture(const GrTextureDesc& desc, const void* srcData, size_t rowBytes) { if (kUnknown_GrPixelConfig == desc.fConfig) { return NULL; } if ((desc.fFlags & kRenderTarget_GrTextureFlagBit) && !this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { return NULL; } this->handleDirtyContext(); GrTexture* tex = this->onCreateTexture(desc, srcData, rowBytes); if (NULL != tex && (kRenderTarget_GrTextureFlagBit & desc.fFlags) && !(kNoStencil_GrTextureFlagBit & desc.fFlags)) { SkASSERT(NULL != tex->asRenderTarget()); // TODO: defer this and attach dynamically if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) { tex->unref(); return NULL; } } return tex; }