本文整理汇总了C++中GrContext::caps方法的典型用法代码示例。如果您正苦于以下问题:C++ GrContext::caps方法的具体用法?C++ GrContext::caps怎么用?C++ GrContext::caps使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrContext
的用法示例。
在下文中一共展示了GrContext::caps方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GrImageInfoToSurfaceDesc
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
SkBitmap bm = create_bm();
const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bm.info(), *context->caps());
sk_sp<GrTextureProxy> proxy(GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
desc, SkBudgeted::kNo,
bm.getPixels(), bm.rowBytes()));
if (!proxy) {
return;
}
sk_sp<SkSpecialImage> fullSImg(SkSpecialImage::MakeDeferredFromGpu(
context,
SkIRect::MakeWH(kFullSize, kFullSize),
kNeedNewImageUniqueID_SpecialImage,
proxy, nullptr));
const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
{
sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeDeferredFromGpu(
context, subset,
kNeedNewImageUniqueID_SpecialImage,
std::move(proxy), nullptr));
test_image(subSImg1, reporter, context, true, kPad, kFullSize);
}
{
sk_sp<SkSpecialImage> subSImg2(fullSImg->makeSubset(subset));
test_image(subSImg2, reporter, context, true, kPad, kFullSize);
}
}
示例2: onDraw
void onDraw(SkCanvas* canvas) override {
GrRenderTargetContext* renderTargetContext =
canvas->internal_private_accessTopLayerRenderTargetContext();
if (!renderTargetContext) {
skiagm::GM::DrawGpuOnlyMessage(canvas);
return;
}
GrContext* context = canvas->getGrContext();
if (!context) {
return;
}
GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
sk_sp<GrTextureProxy> proxy[3];
for (int i = 0; i < 3; ++i) {
int index = (0 == i) ? 0 : 1;
GrSurfaceDesc desc;
desc.fWidth = fBmp[index].width();
desc.fHeight = fBmp[index].height();
desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[index].info(), *context->caps());
SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
proxy[i] = proxyProvider->createTextureProxy(
desc, SkBudgeted::kYes, fBmp[index].getPixels(), fBmp[index].rowBytes());
if (!proxy[i]) {
return;
}
}
constexpr SkScalar kDrawPad = 10.f;
constexpr SkScalar kTestPad = 10.f;
constexpr SkScalar kColorSpaceOffset = 36.f;
SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
SkRect renderRect =
SkRect::MakeWH(SkIntToScalar(fBmp[0].width()), SkIntToScalar(fBmp[0].height()));
renderRect.outset(kDrawPad, kDrawPad);
SkScalar y = kDrawPad + kTestPad + space * kColorSpaceOffset;
SkScalar x = kDrawPad + kTestPad;
GrPaint grPaint;
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
auto fp = GrYUVtoRGBEffect::Make(proxy[0], proxy[1], proxy[2], sizes,
static_cast<SkYUVColorSpace>(space), true);
if (fp) {
SkMatrix viewMatrix;
viewMatrix.setTranslate(x, y);
grPaint.addColorFragmentProcessor(std::move(fp));
std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(
std::move(grPaint), viewMatrix, renderRect, GrAAType::kNone));
renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
}
}
}
示例3: rasterImage
// Test out the SkSpecialImage::makeTextureImage entry point
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_MakeTexture, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
SkBitmap bm = create_bm();
const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
{
// raster
sk_sp<SkSpecialImage> rasterImage(SkSpecialImage::MakeFromRaster(
SkIRect::MakeWH(kFullSize,
kFullSize),
bm));
{
sk_sp<SkSpecialImage> fromRaster(rasterImage->makeTextureImage(context));
test_texture_backed(reporter, rasterImage, fromRaster);
}
{
sk_sp<SkSpecialImage> subRasterImage(rasterImage->makeSubset(subset));
sk_sp<SkSpecialImage> fromSubRaster(subRasterImage->makeTextureImage(context));
test_texture_backed(reporter, subRasterImage, fromSubRaster);
}
}
{
// gpu
const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bm.info(), *context->caps());
sk_sp<GrTextureProxy> proxy(GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
desc, SkBudgeted::kNo,
bm.getPixels(), bm.rowBytes()));
if (!proxy) {
return;
}
sk_sp<SkSpecialImage> gpuImage(SkSpecialImage::MakeDeferredFromGpu(
context,
SkIRect::MakeWH(kFullSize, kFullSize),
kNeedNewImageUniqueID_SpecialImage,
std::move(proxy), nullptr));
{
sk_sp<SkSpecialImage> fromGPU(gpuImage->makeTextureImage(context));
test_texture_backed(reporter, gpuImage, fromGPU);
}
{
sk_sp<SkSpecialImage> subGPUImage(gpuImage->makeSubset(subset));
sk_sp<SkSpecialImage> fromSubGPU(subGPUImage->makeTextureImage(context));
test_texture_backed(reporter, subGPUImage, fromSubGPU);
}
}
}
示例4: pixels
// 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);
}
示例5: createGPUSurface
SkSurface* Request::createGPUSurface() {
GrContext* context = fContextFactory->get(GrContextFactory::kNative_GLContextType,
GrContextFactory::kNone_GLContextOptions);
int maxRTSize = context->caps()->maxRenderTargetSize();
SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize),
SkTMin(kImageHeight, maxRTSize),
kN32_SkColorType, kPremul_SkAlphaType);
uint32_t flags = 0;
SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
SkSurface* surface = SkSurface::NewRenderTarget(context, SkBudgeted::kNo, info, 0,
&props);
return surface;
}
示例6: target
DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.fGrContext;
GrTextureDesc desc;
desc.fHeight = 1;
desc.fWidth = 1;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = kRGBA_8888_GrPixelConfig;
SkAutoTUnref<GrTexture> target(context->textureProvider()->createTexture(desc,
SkBudgeted::kYes));
if (!target) {
ERRORF(reporter, "Could not create render target.");
return;
}
SkAutoTUnref<GrDrawContext> dc(context->drawContext(target->asRenderTarget()));
if (!dc) {
ERRORF(reporter, "Could not create draw context.");
return;
}
int attribCnt = context->caps()->maxVertexAttributes();
if (!attribCnt) {
ERRORF(reporter, "No attributes allowed?!");
return;
}
context->flush();
context->resetGpuStats();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
SkAutoTUnref<GrDrawBatch> batch;
GrPipelineBuilder pb;
pb.setRenderTarget(target->asRenderTarget());
// This one should succeed.
batch.reset(new Batch(attribCnt));
dc->drawContextPriv().testingOnly_drawBatch(pb, batch);
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
context->resetGpuStats();
// This one should fail.
batch.reset(new Batch(attribCnt+1));
dc->drawContextPriv().testingOnly_drawBatch(pb, batch);
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 1);
#endif
}
示例7: setupSurface
// TODO factor this out into functions, also handle CPU path
SkSurface* setupSurface(GrContextFactory* factory) {
GrContext* context = factory->get(GrContextFactory::kNative_GLContextType,
GrContextFactory::kNone_GLContextOptions);
int maxRTSize = context->caps()->maxRenderTargetSize();
SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize),
SkTMin(kImageHeight, maxRTSize),
kN32_SkColorType, kPremul_SkAlphaType);
uint32_t flags = 0;
SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
SkSurface* surface = SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0,
&props);
SkASSERT(surface);
SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContextType,
GrContextFactory::kNone_GLContextOptions).fGLContext;
gl->makeCurrent();
return surface;
}
示例8: drawContext
DEF_GPUTEST_FOR_ALL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
1, 1, kRGBA_8888_GrPixelConfig));
if (!drawContext) {
ERRORF(reporter, "Could not create draw context.");
return;
}
int attribCnt = context->caps()->maxVertexAttributes();
if (!attribCnt) {
ERRORF(reporter, "No attributes allowed?!");
return;
}
context->flush();
context->resetGpuStats();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
SkAutoTUnref<GrDrawBatch> batch;
GrPaint grPaint;
// This one should succeed.
batch.reset(new Batch(attribCnt));
drawContext->drawContextPriv().testingOnly_drawBatch(grPaint, batch);
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
context->resetGpuStats();
// This one should fail.
batch.reset(new Batch(attribCnt+1));
drawContext->drawContextPriv().testingOnly_drawBatch(grPaint, batch);
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 1);
#endif
}
示例9: renderTargetContext
DEF_GPUTEST_FOR_ALL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
sk_sp<GrRenderTargetContext> renderTargetContext(context->makeDeferredRenderTargetContext(
SkBackingFit::kApprox,
1, 1, kRGBA_8888_GrPixelConfig,
nullptr));
if (!renderTargetContext) {
ERRORF(reporter, "Could not create render target context.");
return;
}
int attribCnt = context->caps()->maxVertexAttributes();
if (!attribCnt) {
ERRORF(reporter, "No attributes allowed?!");
return;
}
context->flush();
context->resetGpuStats();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
GrPaint grPaint;
// This one should succeed.
renderTargetContext->priv().testingOnly_addDrawOp(Op::Make(attribCnt));
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 0);
#endif
context->resetGpuStats();
renderTargetContext->priv().testingOnly_addDrawOp(Op::Make(attribCnt + 1));
context->flush();
#if GR_GPU_STATS
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
REPORTER_ASSERT(reporter, context->getGpu()->stats()->numFailedDraws() == 1);
#endif
}
示例10: mainSurface
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(EmptySurfaceSemaphoreTest, reporter, ctxInfo) {
GrContext* ctx = ctxInfo.grContext();
if (!ctx->caps()->fenceSyncSupport()) {
return;
}
const SkImageInfo ii = SkImageInfo::Make(MAIN_W, MAIN_H, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);
sk_sp<SkSurface> mainSurface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo,
ii, 0, kTopLeft_GrSurfaceOrigin,
nullptr));
// Flush surface once without semaphores to make sure there is no peneding IO for it.
mainSurface->flush();
GrBackendSemaphore semaphore;
GrSemaphoresSubmitted submitted = mainSurface->flushAndSignalSemaphores(1, &semaphore);
REPORTER_ASSERT(reporter, GrSemaphoresSubmitted::kYes == submitted);
if (kOpenGL_GrBackend == ctxInfo.backend()) {
GrGLGpu* gpu = static_cast<GrGLGpu*>(ctx->contextPriv().getGpu());
const GrGLInterface* interface = gpu->glInterface();
GrGLsync sync = semaphore.glSync();
REPORTER_ASSERT(reporter, sync);
bool result;
GR_GL_CALL_RET(interface, result, IsSync(sync));
REPORTER_ASSERT(reporter, result);
}
#ifdef SK_VULKAN
if (kVulkan_GrBackend == ctxInfo.backend()) {
GrVkGpu* gpu = static_cast<GrVkGpu*>(ctx->contextPriv().getGpu());
const GrVkInterface* interface = gpu->vkInterface();
VkDevice device = gpu->device();
VkQueue queue = gpu->queue();
VkCommandPool cmdPool = gpu->cmdPool();
VkCommandBuffer cmdBuffer;
// Create Command Buffer
const VkCommandBufferAllocateInfo cmdInfo = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
nullptr, // pNext
cmdPool, // commandPool
VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1 // bufferCount
};
VkResult err = GR_VK_CALL(interface, AllocateCommandBuffers(device, &cmdInfo, &cmdBuffer));
if (err) {
return;
}
VkCommandBufferBeginInfo cmdBufferBeginInfo;
memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdBufferBeginInfo.pNext = nullptr;
cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
cmdBufferBeginInfo.pInheritanceInfo = nullptr;
GR_VK_CALL_ERRCHECK(interface, BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
GR_VK_CALL_ERRCHECK(interface, EndCommandBuffer(cmdBuffer));
VkFenceCreateInfo fenceInfo;
VkFence fence;
memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
err = GR_VK_CALL(interface, CreateFence(device, &fenceInfo, nullptr, &fence));
SkASSERT(!err);
VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkSubmitInfo submitInfo;
memset(&submitInfo, 0, sizeof(VkSubmitInfo));
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pNext = nullptr;
submitInfo.waitSemaphoreCount = 1;
VkSemaphore vkSem = semaphore.vkSemaphore();
submitInfo.pWaitSemaphores = &vkSem;
submitInfo.pWaitDstStageMask = &waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cmdBuffer;
submitInfo.signalSemaphoreCount = 0;
submitInfo.pSignalSemaphores = nullptr;
GR_VK_CALL_ERRCHECK(interface, QueueSubmit(queue, 1, &submitInfo, fence));
err = GR_VK_CALL(interface, WaitForFences(device, 1, &fence, true, 3000000000));
REPORTER_ASSERT(reporter, err != VK_TIMEOUT);
GR_VK_CALL(interface, DestroyFence(device, fence, nullptr));
GR_VK_CALL(interface, DestroySemaphore(device, vkSem, nullptr));
// If the above test fails the wait semaphore will never be signaled which can cause the
// device to hang when tearing down (even if just tearing down GL). So we Fail here to
// kill things.
if (err == VK_TIMEOUT) {
SK_ABORT("Waiting on semaphore indefinitely");
}
}
#endif
//.........这里部分代码省略.........
示例11: surface_semaphore_test
void surface_semaphore_test(skiatest::Reporter* reporter,
const sk_gpu_test::ContextInfo& mainInfo,
const sk_gpu_test::ContextInfo& childInfo1,
const sk_gpu_test::ContextInfo& childInfo2,
bool flushContext) {
GrContext* mainCtx = mainInfo.grContext();
if (!mainCtx->caps()->fenceSyncSupport()) {
return;
}
const SkImageInfo ii = SkImageInfo::Make(MAIN_W, MAIN_H, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);
sk_sp<SkSurface> mainSurface(SkSurface::MakeRenderTarget(mainCtx, SkBudgeted::kNo,
ii, 0, kTopLeft_GrSurfaceOrigin,
nullptr));
SkCanvas* mainCanvas = mainSurface->getCanvas();
mainCanvas->clear(SK_ColorBLUE);
SkAutoTArray<GrBackendSemaphore> semaphores(2);
#ifdef SK_VULKAN
if (kVulkan_GrBackend == mainInfo.backend()) {
// Initialize the secondary semaphore instead of having Ganesh create one internally
GrVkGpu* gpu = static_cast<GrVkGpu*>(mainCtx->contextPriv().getGpu());
const GrVkInterface* interface = gpu->vkInterface();
VkDevice device = gpu->device();
VkSemaphore vkSem;
VkSemaphoreCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
GR_VK_CALL_ERRCHECK(interface, CreateSemaphore(device, &createInfo, nullptr, &vkSem));
semaphores[1].initVulkan(vkSem);
}
#endif
if (flushContext) {
mainCtx->flushAndSignalSemaphores(2, semaphores.get());
} else {
mainSurface->flushAndSignalSemaphores(2, semaphores.get());
}
sk_sp<SkImage> mainImage = mainSurface->makeImageSnapshot();
GrBackendTexture backendTexture = mainImage->getBackendTexture(false);
draw_child(reporter, childInfo1, backendTexture, semaphores[0]);
#ifdef SK_VULKAN
if (kVulkan_GrBackend == mainInfo.backend()) {
// In Vulkan we need to make sure we are sending the correct VkImageLayout in with the
// backendImage. After the first child draw the layout gets changed to SHADER_READ, so
// we just manually set that here.
GrVkImageInfo vkInfo;
SkAssertResult(backendTexture.getVkImageInfo(&vkInfo));
vkInfo.updateImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
#endif
draw_child(reporter, childInfo2, backendTexture, semaphores[1]);
}
示例12: copy_on_gpu
static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset,
const CopyParams& copyParams) {
SkASSERT(!subset || !subset->isEmpty());
GrContext* context = inputTexture->getContext();
SkASSERT(context);
const GrCaps* caps = context->caps();
// Either it's a cache miss or the original wasn't cached to begin with.
GrSurfaceDesc rtDesc = inputTexture->desc();
rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
rtDesc.fWidth = copyParams.fWidth;
rtDesc.fHeight = copyParams.fHeight;
rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
// If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise,
// fail.
if (!caps->isConfigRenderable(rtDesc.fConfig, false)) {
if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) {
if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
rtDesc.fConfig = kAlpha_8_GrPixelConfig;
} else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
rtDesc.fConfig = kSkia8888_GrPixelConfig;
} else {
return nullptr;
}
} else if (kRGB_GrColorComponentFlags ==
(kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDesc.fConfig))) {
if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
rtDesc.fConfig = kSkia8888_GrPixelConfig;
} else {
return nullptr;
}
} else {
return nullptr;
}
}
SkAutoTUnref<GrTexture> copy(context->textureProvider()->createTexture(rtDesc,
SkBudgeted::kYes));
if (!copy) {
return nullptr;
}
// TODO: If no scaling is being performed then use copySurface.
GrPaint paint;
paint.setGammaCorrect(true);
// TODO: Initializing these values for no reason cause the compiler is complaining
SkScalar sx = 0.f;
SkScalar sy = 0.f;
if (subset) {
sx = 1.f / inputTexture->width();
sy = 1.f / inputTexture->height();
}
if (copyParams.fFilter != GrTextureParams::kNone_FilterMode && subset &&
(subset->width() != copyParams.fWidth || subset->height() != copyParams.fHeight)) {
SkRect domain;
domain.fLeft = (subset->fLeft + 0.5f) * sx;
domain.fTop = (subset->fTop + 0.5f)* sy;
domain.fRight = (subset->fRight - 0.5f) * sx;
domain.fBottom = (subset->fBottom - 0.5f) * sy;
// This would cause us to read values from outside the subset. Surely, the caller knows
// better!
SkASSERT(copyParams.fFilter != GrTextureParams::kMipMap_FilterMode);
paint.addColorFragmentProcessor(
GrTextureDomainEffect::Make(inputTexture, SkMatrix::I(), domain,
GrTextureDomain::kClamp_Mode,
copyParams.fFilter));
} else {
GrTextureParams params(SkShader::kClamp_TileMode, copyParams.fFilter);
paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
}
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkRect localRect;
if (subset) {
localRect = SkRect::Make(*subset);
localRect.fLeft *= sx;
localRect.fTop *= sy;
localRect.fRight *= sx;
localRect.fBottom *= sy;
} else {
localRect = SkRect::MakeWH(1.f, 1.f);
}
sk_sp<GrDrawContext> drawContext(context->drawContext(sk_ref_sp(copy->asRenderTarget())));
if (!drawContext) {
return nullptr;
}
SkRect dstRect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
drawContext->fillRectToRect(GrNoClip(), paint, SkMatrix::I(), dstRect, localRect);
return copy.release();
}
示例13: stretch_texture
// creates a new texture that is the input texture scaled up. If optionalKey is valid it will be
// set on the new texture. stretch controls whether the scaling is done using nearest or bilerp
// filtering and the size to stretch the texture to.
GrTexture* stretch_texture(GrTexture* inputTexture, const SkGrStretch& stretch,
SkPixelRef* pixelRef,
const GrUniqueKey& optionalKey) {
SkASSERT(SkGrStretch::kNone_Type != stretch.fType);
GrContext* context = inputTexture->getContext();
SkASSERT(context);
const GrCaps* caps = context->caps();
// Either it's a cache miss or the original wasn't cached to begin with.
GrSurfaceDesc rtDesc = inputTexture->desc();
rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
rtDesc.fWidth = stretch.fWidth;
rtDesc.fHeight = stretch.fHeight;
rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
// If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise,
// fail.
if (!caps->isConfigRenderable(rtDesc.fConfig, false)) {
if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) {
if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
rtDesc.fConfig = kAlpha_8_GrPixelConfig;
} else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
rtDesc.fConfig = kSkia8888_GrPixelConfig;
} else {
return nullptr;
}
} else if (kRGB_GrColorComponentFlags ==
(kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDesc.fConfig))) {
if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
rtDesc.fConfig = kSkia8888_GrPixelConfig;
} else {
return nullptr;
}
} else {
return nullptr;
}
}
SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optionalKey, rtDesc,
pixelRef, nullptr,0));
if (!stretched) {
return nullptr;
}
GrPaint paint;
// If filtering is not desired then we want to ensure all texels in the resampled image are
// copies of texels from the original.
GrTextureParams params(SkShader::kClamp_TileMode,
SkGrStretch::kBilerp_Type == stretch.fType ?
GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
SkRect localRect = SkRect::MakeWH(1.f, 1.f);
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext());
if (!drawContext) {
return nullptr;
}
drawContext->drawNonAARectToRect(stretched->asRenderTarget(), GrClip::WideOpen(), paint,
SkMatrix::I(), rect, localRect);
return stretched.detach();
}
示例14: mipMapParams
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SRGBMipMaps, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
if (!context->caps()->srgbSupport()) {
return;
}
const int rtS = 16;
const int texS = rtS * 2;
// Fill texture with a dither of black and 60% sRGB (~ 32.5% linear) gray. Although there is
// only one likely failure mode (doing a direct downsample of the sRGB values), this pattern
// maximizes the minimum error across all three conceivable failure modes:
// 1) Likely incorrect:
// (A + B) / 2
// 2) No input decode, decode output:
// linear_to_srgb((A + B) / 2)
// 3) Decode input, no output encode:
// (srgb_to_linear(A) + srgb_to_linear(B)) / 2
const U8CPU srgb60 = sk_float_round2int(0.6f * 255.0f);
static const SkPMColor colors[2] = {
SkPackARGB32(0xFF, srgb60, srgb60, srgb60),
SkPackARGB32(0xFF, 0x00, 0x00, 0x00)
};
uint32_t texData[texS * texS];
for (int y = 0; y < texS; ++y) {
for (int x = 0; x < texS; ++x) {
texData[y * texS + x] = colors[(x + y) % 2];
}
}
// We can be pretty generous with the error detection, thanks to the choice of input.
// The closest likely failure mode is off by > 0.1, so anything that encodes within
// 10/255 of optimal is more than good enough for this test.
const U8CPU expectedSRGB = sk_float_round2int(
linear_to_srgb(srgb_to_linear(srgb60 / 255.0f) / 2.0f) * 255.0f);
const U8CPU expectedLinear = srgb60 / 2;
const U8CPU error = 10;
// Create our test texture
GrSurfaceDesc desc;
desc.fFlags = kNone_GrSurfaceFlags;
desc.fConfig = kSRGBA_8888_GrPixelConfig;
desc.fWidth = texS;
desc.fHeight = texS;
GrTextureProvider* texProvider = context->textureProvider();
SkAutoTUnref<GrTexture> texture(texProvider->createTexture(desc, SkBudgeted::kNo, texData, 0));
// Create two render target contexts (L32 and S32)
sk_sp<SkColorSpace> srgbColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
sk_sp<GrRenderTargetContext> l32RenderTargetContext = context->makeRenderTargetContext(
SkBackingFit::kExact, rtS, rtS, kRGBA_8888_GrPixelConfig, nullptr);
sk_sp<GrRenderTargetContext> s32RenderTargetContext = context->makeRenderTargetContext(
SkBackingFit::kExact, rtS, rtS, kSRGBA_8888_GrPixelConfig, std::move(srgbColorSpace));
SkRect rect = SkRect::MakeWH(SkIntToScalar(rtS), SkIntToScalar(rtS));
GrNoClip noClip;
GrPaint paint;
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
GrTextureParams mipMapParams(SkShader::kRepeat_TileMode, GrTextureParams::kMipMap_FilterMode);
paint.addColorTextureProcessor(texture, nullptr, SkMatrix::MakeScale(0.5f), mipMapParams);
// 1) Draw texture to S32 surface (should generate/use sRGB mips)
paint.setGammaCorrect(true);
s32RenderTargetContext->drawRect(noClip, paint, SkMatrix::I(), rect);
read_and_check_pixels(reporter, s32RenderTargetContext->asTexture().get(), expectedSRGB, error,
"first render of sRGB");
// 2) Draw texture to L32 surface (should generate/use linear mips)
paint.setGammaCorrect(false);
l32RenderTargetContext->drawRect(noClip, paint, SkMatrix::I(), rect);
read_and_check_pixels(reporter, l32RenderTargetContext->asTexture().get(), expectedLinear,
error, "re-render as linear");
// 3) Go back to sRGB
paint.setGammaCorrect(true);
s32RenderTargetContext->drawRect(noClip, paint, SkMatrix::I(), rect);
read_and_check_pixels(reporter, s32RenderTargetContext->asTexture().get(), expectedSRGB, error,
"re-render as sRGB");
}
示例15: sizeof
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ApplyGamma, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
static const int kW = 256;
static const int kH = 256;
static const size_t kRowBytes = sizeof(uint32_t) * kW;
GrSurfaceDesc baseDesc;
baseDesc.fConfig = kRGBA_8888_GrPixelConfig;
baseDesc.fWidth = kW;
baseDesc.fHeight = kH;
const SkImageInfo ii = SkImageInfo::MakeN32Premul(kW, kH);
SkAutoTMalloc<uint32_t> srcPixels(kW * kH);
for (int y = 0; y < kH; ++y) {
for (int x = 0; x < kW; ++x) {
srcPixels.get()[y*kW+x] = SkPreMultiplyARGB(x, y, x, 0xFF);
}
}
SkBitmap bm;
bm.installPixels(ii, srcPixels.get(), kRowBytes);
SkAutoTMalloc<uint32_t> read(kW * kH);
// We allow more error on GPUs with lower precision shader variables.
float error = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.2f : 0.5f;
for (auto toSRGB : { false, true }) {
sk_sp<SkSurface> dst(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii));
if (!dst) {
ERRORF(reporter, "Could not create surfaces for copy surface test.");
continue;
}
SkCanvas* dstCanvas = dst->getCanvas();
dstCanvas->clear(SK_ColorRED);
dstCanvas->flush();
SkPaint gammaPaint;
gammaPaint.setBlendMode(SkBlendMode::kSrc);
gammaPaint.setColorFilter(toSRGB ? SkColorFilter::MakeLinearToSRGBGamma()
: SkColorFilter::MakeSRGBToLinearGamma());
dstCanvas->drawBitmap(bm, 0, 0, &gammaPaint);
dstCanvas->flush();
sk_memset32(read.get(), 0, kW * kH);
if (!dstCanvas->readPixels(ii, read.get(), kRowBytes, 0, 0)) {
ERRORF(reporter, "Error calling readPixels");
continue;
}
bool abort = false;
// Validate that pixels were copied/transformed correctly.
for (int y = 0; y < kH && !abort; ++y) {
for (int x = 0; x < kW && !abort; ++x) {
uint32_t r = read.get()[y * kW + x];
uint32_t s = srcPixels.get()[y * kW + x];
uint32_t expected;
if (!check_gamma(s, r, toSRGB, error, &expected)) {
ERRORF(reporter, "Expected dst %d,%d to contain 0x%08x "
"from src 0x%08x and mode %s. Got %08x", x, y, expected, s,
toSRGB ? "ToSRGB" : "ToLinear", r);
abort = true;
break;
}
}
}
}
}