| /* |
| * Copyright 2016 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| #include <vector> |
| |
| #include "gm.h" |
| #include "SkImage.h" |
| #include "SkMipMap.h" |
| #include "Resources.h" |
| |
| #if SK_SUPPORT_GPU |
| #include "GrContext.h" |
| |
| // Helper function that uploads the given SkImage using MakeFromDeferredTextureImageData and then |
| // draws the uploaded version at the specified coordinates. |
| static void DrawDeferredTextureImageData(SkCanvas* canvas, |
| const char* resourceName, |
| SkImage::DeferredTextureImageUsageParams* params, |
| SkColorType dstColorType) { |
| GrContext* context = canvas->getGrContext(); |
| if (!context) { |
| skiagm::GM::DrawGpuOnlyMessage(canvas); |
| return; |
| } |
| sk_sp<GrContextThreadSafeProxy> proxy(context->threadSafeProxy()); |
| |
| |
| |
| sk_sp<SkImage> encodedImage = GetResourceAsImage(resourceName); |
| if (!encodedImage) { |
| SkDebugf("\nCould not load resource.\n"); |
| return; |
| } |
| |
| size_t requiredMemoryInBytes = encodedImage->getDeferredTextureImageData( |
| *proxy, params, 1, nullptr, canvas->imageInfo().colorSpace(), dstColorType); |
| if (requiredMemoryInBytes == 0) { |
| SkDebugf("\nCould not create DeferredTextureImageData.\n"); |
| return; |
| } |
| |
| std::vector<uint8_t> memory; |
| memory.resize(requiredMemoryInBytes); |
| encodedImage->getDeferredTextureImageData( |
| *proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace(), dstColorType); |
| sk_sp<SkImage> uploadedEncodedImage = SkImage::MakeFromDeferredTextureImageData( |
| context, memory.data(), SkBudgeted::kNo); |
| |
| canvas->drawImage(uploadedEncodedImage, 10, 10); |
| |
| |
| |
| SkBitmap bitmap; |
| if (!GetResourceAsBitmap(resourceName, &bitmap)) { |
| SkDebugf("\nCould not decode resource.\n"); |
| return; |
| } |
| sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap); |
| |
| requiredMemoryInBytes = decodedImage->getDeferredTextureImageData( |
| *proxy, params, 1, nullptr, canvas->imageInfo().colorSpace(), dstColorType); |
| if (requiredMemoryInBytes == 0) { |
| SkDebugf("\nCould not create DeferredTextureImageData.\n"); |
| return; |
| } |
| |
| memory.resize(requiredMemoryInBytes); |
| decodedImage->getDeferredTextureImageData( |
| *proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace(), dstColorType); |
| sk_sp<SkImage> uploadedDecodedImage = SkImage::MakeFromDeferredTextureImageData( |
| context, memory.data(), SkBudgeted::kNo); |
| |
| canvas->drawImage(uploadedDecodedImage, encodedImage->width() + 20, 10); |
| } |
| |
| static void DrawDeferredTextureImageMipMapTree(SkCanvas* canvas, SkImage* image, |
| SkImage::DeferredTextureImageUsageParams* params, |
| SkColorType dstColorType) { |
| GrContext* context = canvas->getGrContext(); |
| if (!context) { |
| skiagm::GM::DrawGpuOnlyMessage(canvas); |
| return; |
| } |
| sk_sp<GrContextThreadSafeProxy> proxy(context->threadSafeProxy()); |
| |
| SkPaint paint; |
| paint.setFilterQuality(params->fQuality); |
| |
| int mipLevelCount = SkMipMap::ComputeLevelCount(image->width(), image->height()); |
| size_t requiredMemoryInBytes = image->getDeferredTextureImageData( |
| *proxy, params, 1, nullptr, canvas->imageInfo().colorSpace(), dstColorType); |
| if (requiredMemoryInBytes == 0) { |
| SkDebugf("\nCould not create DeferredTextureImageData.\n"); |
| return; |
| } |
| |
| std::vector<uint8_t> memory; |
| memory.resize(requiredMemoryInBytes); |
| image->getDeferredTextureImageData( |
| *proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace(), dstColorType); |
| sk_sp<SkImage> uploadedImage = SkImage::MakeFromDeferredTextureImageData( |
| context, memory.data(), SkBudgeted::kNo); |
| |
| // draw a column using deferred texture images |
| SkScalar offsetHeight = 10.f; |
| // handle base mipmap level |
| canvas->save(); |
| canvas->translate(10.f, offsetHeight); |
| canvas->drawImage(uploadedImage, 0, 0, &paint); |
| canvas->restore(); |
| offsetHeight += image->height() + 10; |
| // handle generated mipmap levels |
| for (int i = 0; i < mipLevelCount; i++) { |
| SkISize mipSize = SkMipMap::ComputeLevelSize(image->width(), image->height(), i); |
| canvas->save(); |
| canvas->translate(10.f, offsetHeight); |
| canvas->scale(mipSize.width() / static_cast<float>(image->width()), |
| mipSize.height() / static_cast<float>(image->height())); |
| canvas->drawImage(uploadedImage, 0, 0, &paint); |
| canvas->restore(); |
| offsetHeight += mipSize.height() + 10; |
| } |
| |
| // draw a column using SkImage |
| offsetHeight = 10; |
| // handle base mipmap level |
| canvas->save(); |
| canvas->translate(image->width() + 20.f, offsetHeight); |
| canvas->drawImage(image, 0, 0, &paint); |
| canvas->restore(); |
| offsetHeight += image->height() + 10; |
| // handle generated mipmap levels |
| for (int i = 0; i < mipLevelCount; i++) { |
| SkISize mipSize = SkMipMap::ComputeLevelSize(image->width(), image->height(), i); |
| canvas->save(); |
| canvas->translate(image->width() + 20.f, offsetHeight); |
| canvas->scale(mipSize.width() / static_cast<float>(image->width()), |
| mipSize.height() / static_cast<float>(image->height())); |
| canvas->drawImage(image, 0, 0, &paint); |
| canvas->restore(); |
| offsetHeight += mipSize.height() + 10; |
| } |
| } |
| |
| DEF_SIMPLE_GM(deferred_texture_image_none, canvas, 512 + 512 + 30, 512 + 20) { |
| auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f), |
| kNone_SkFilterQuality, 0); |
| DrawDeferredTextureImageData(canvas, "images/mandrill_512.png", ¶ms, kN32_SkColorType); |
| } |
| |
| DEF_SIMPLE_GM(deferred_texture_image_low, canvas, 512 + 512 + 30, 512 + 20) { |
| auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f), |
| kLow_SkFilterQuality, 0); |
| DrawDeferredTextureImageData(canvas, "images/mandrill_512.png", ¶ms, kN32_SkColorType); |
| } |
| |
| DEF_SIMPLE_GM(deferred_texture_image_low_dithered, canvas, 180 + 180 + 30, 180 + 20) { |
| auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), |
| kLow_SkFilterQuality, 0); |
| DrawDeferredTextureImageData(canvas, "images/dog.jpg", ¶ms, kARGB_4444_SkColorType); |
| } |
| |
| DEF_SIMPLE_GM(deferred_texture_image_medium_encoded, canvas, 512 + 512 + 30, 1110) { |
| sk_sp<SkImage> encodedImage = GetResourceAsImage("images/mandrill_512.png"); |
| if (!encodedImage) { |
| SkDebugf("\nCould not load resource.\n"); |
| return; |
| } |
| |
| auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), |
| kMedium_SkFilterQuality, 0); |
| DrawDeferredTextureImageMipMapTree(canvas, encodedImage.get(), ¶ms, kN32_SkColorType); |
| } |
| |
| DEF_SIMPLE_GM(deferred_texture_image_medium_decoded, canvas, 512 + 512 + 30, 1110) { |
| SkBitmap bitmap; |
| if (!GetResourceAsBitmap("images/mandrill_512.png", &bitmap)) { |
| SkDebugf("\nCould not decode resource.\n"); |
| return; |
| } |
| sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap); |
| |
| auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), |
| kMedium_SkFilterQuality, 0); |
| DrawDeferredTextureImageMipMapTree(canvas, decodedImage.get(), ¶ms, kN32_SkColorType); |
| } |
| |
| DEF_SIMPLE_GM(deferred_texture_image_high, canvas, 512 + 512 + 30, 512 + 20) { |
| auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f), |
| kHigh_SkFilterQuality, 0); |
| DrawDeferredTextureImageData(canvas, "images/mandrill_512.png", ¶ms, kN32_SkColorType); |
| } |
| |
| DEF_SIMPLE_GM(deferred_texture_image_medium_encoded_indexed, canvas, 128 + 128 + 30, 340) { |
| sk_sp<SkImage> encodedImage = GetResourceAsImage("images/color_wheel.gif"); |
| if (!encodedImage) { |
| SkDebugf("\nCould not load resource.\n"); |
| return; |
| } |
| |
| auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), |
| kMedium_SkFilterQuality, 0); |
| DrawDeferredTextureImageMipMapTree(canvas, encodedImage.get(), ¶ms, kN32_SkColorType); |
| } |
| |
| DEF_SIMPLE_GM(deferred_texture_image_medium_decoded_indexed, canvas, 128 + 128 + 30, 340) { |
| SkBitmap bitmap; |
| if (!GetResourceAsBitmap("images/color_wheel.gif", &bitmap)) { |
| SkDebugf("\nCould not decode resource.\n"); |
| return; |
| } |
| sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap); |
| |
| auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), |
| kMedium_SkFilterQuality, 0); |
| DrawDeferredTextureImageMipMapTree(canvas, decodedImage.get(), ¶ms, kN32_SkColorType); |
| } |
| |
| #endif |