1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 #include <vector> 8 9 #include "gm.h" 10 #include "SkImage.h" 11 #include "SkMipMap.h" 12 #include "Resources.h" 13 14 #if SK_SUPPORT_GPU 15 #include "GrContext.h" 16 17 // Helper function that uploads the given SkImage using MakeFromDeferredTextureImageData and then 18 // draws the uploaded version at the specified coordinates. 19 static void DrawDeferredTextureImageData(SkCanvas* canvas, 20 const char* resourceName, 21 SkImage::DeferredTextureImageUsageParams* params, 22 SkColorType dstColorType) { 23 GrContext* context = canvas->getGrContext(); 24 if (!context) { 25 skiagm::GM::DrawGpuOnlyMessage(canvas); 26 return; 27 } 28 sk_sp<GrContextThreadSafeProxy> proxy(context->threadSafeProxy()); 29 30 31 32 sk_sp<SkImage> encodedImage = GetResourceAsImage(resourceName); 33 if (!encodedImage) { 34 SkDebugf("\nCould not load resource.\n"); 35 return; 36 } 37 38 size_t requiredMemoryInBytes = encodedImage->getDeferredTextureImageData( 39 *proxy, params, 1, nullptr, canvas->imageInfo().colorSpace(), dstColorType); 40 if (requiredMemoryInBytes == 0) { 41 SkDebugf("\nCould not create DeferredTextureImageData.\n"); 42 return; 43 } 44 45 std::vector<uint8_t> memory; 46 memory.resize(requiredMemoryInBytes); 47 encodedImage->getDeferredTextureImageData( 48 *proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace(), dstColorType); 49 sk_sp<SkImage> uploadedEncodedImage = SkImage::MakeFromDeferredTextureImageData( 50 context, memory.data(), SkBudgeted::kNo); 51 52 canvas->drawImage(uploadedEncodedImage, 10, 10); 53 54 55 56 SkBitmap bitmap; 57 if (!GetResourceAsBitmap(resourceName, &bitmap)) { 58 SkDebugf("\nCould not decode resource.\n"); 59 return; 60 } 61 sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap); 62 63 requiredMemoryInBytes = decodedImage->getDeferredTextureImageData( 64 *proxy, params, 1, nullptr, canvas->imageInfo().colorSpace(), dstColorType); 65 if (requiredMemoryInBytes == 0) { 66 SkDebugf("\nCould not create DeferredTextureImageData.\n"); 67 return; 68 } 69 70 memory.resize(requiredMemoryInBytes); 71 decodedImage->getDeferredTextureImageData( 72 *proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace(), dstColorType); 73 sk_sp<SkImage> uploadedDecodedImage = SkImage::MakeFromDeferredTextureImageData( 74 context, memory.data(), SkBudgeted::kNo); 75 76 canvas->drawImage(uploadedDecodedImage, encodedImage->width() + 20, 10); 77 } 78 79 static void DrawDeferredTextureImageMipMapTree(SkCanvas* canvas, SkImage* image, 80 SkImage::DeferredTextureImageUsageParams* params, 81 SkColorType dstColorType) { 82 GrContext* context = canvas->getGrContext(); 83 if (!context) { 84 skiagm::GM::DrawGpuOnlyMessage(canvas); 85 return; 86 } 87 sk_sp<GrContextThreadSafeProxy> proxy(context->threadSafeProxy()); 88 89 SkPaint paint; 90 paint.setFilterQuality(params->fQuality); 91 92 int mipLevelCount = SkMipMap::ComputeLevelCount(image->width(), image->height()); 93 size_t requiredMemoryInBytes = image->getDeferredTextureImageData( 94 *proxy, params, 1, nullptr, canvas->imageInfo().colorSpace(), dstColorType); 95 if (requiredMemoryInBytes == 0) { 96 SkDebugf("\nCould not create DeferredTextureImageData.\n"); 97 return; 98 } 99 100 std::vector<uint8_t> memory; 101 memory.resize(requiredMemoryInBytes); 102 image->getDeferredTextureImageData( 103 *proxy, params, 1, memory.data(), canvas->imageInfo().colorSpace(), dstColorType); 104 sk_sp<SkImage> uploadedImage = SkImage::MakeFromDeferredTextureImageData( 105 context, memory.data(), SkBudgeted::kNo); 106 107 // draw a column using deferred texture images 108 SkScalar offsetHeight = 10.f; 109 // handle base mipmap level 110 canvas->save(); 111 canvas->translate(10.f, offsetHeight); 112 canvas->drawImage(uploadedImage, 0, 0, &paint); 113 canvas->restore(); 114 offsetHeight += image->height() + 10; 115 // handle generated mipmap levels 116 for (int i = 0; i < mipLevelCount; i++) { 117 SkISize mipSize = SkMipMap::ComputeLevelSize(image->width(), image->height(), i); 118 canvas->save(); 119 canvas->translate(10.f, offsetHeight); 120 canvas->scale(mipSize.width() / static_cast<float>(image->width()), 121 mipSize.height() / static_cast<float>(image->height())); 122 canvas->drawImage(uploadedImage, 0, 0, &paint); 123 canvas->restore(); 124 offsetHeight += mipSize.height() + 10; 125 } 126 127 // draw a column using SkImage 128 offsetHeight = 10; 129 // handle base mipmap level 130 canvas->save(); 131 canvas->translate(image->width() + 20.f, offsetHeight); 132 canvas->drawImage(image, 0, 0, &paint); 133 canvas->restore(); 134 offsetHeight += image->height() + 10; 135 // handle generated mipmap levels 136 for (int i = 0; i < mipLevelCount; i++) { 137 SkISize mipSize = SkMipMap::ComputeLevelSize(image->width(), image->height(), i); 138 canvas->save(); 139 canvas->translate(image->width() + 20.f, offsetHeight); 140 canvas->scale(mipSize.width() / static_cast<float>(image->width()), 141 mipSize.height() / static_cast<float>(image->height())); 142 canvas->drawImage(image, 0, 0, &paint); 143 canvas->restore(); 144 offsetHeight += mipSize.height() + 10; 145 } 146 } 147 148 DEF_SIMPLE_GM(deferred_texture_image_none, canvas, 512 + 512 + 30, 512 + 20) { 149 auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f), 150 kNone_SkFilterQuality, 0); 151 DrawDeferredTextureImageData(canvas, "mandrill_512.png", ¶ms, kN32_SkColorType); 152 } 153 154 DEF_SIMPLE_GM(deferred_texture_image_low, canvas, 512 + 512 + 30, 512 + 20) { 155 auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f), 156 kLow_SkFilterQuality, 0); 157 DrawDeferredTextureImageData(canvas, "mandrill_512.png", ¶ms, kN32_SkColorType); 158 } 159 160 DEF_SIMPLE_GM(deferred_texture_image_low_dithered, canvas, 180 + 180 + 30, 180 + 20) { 161 auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), 162 kLow_SkFilterQuality, 0); 163 DrawDeferredTextureImageData(canvas, "dog.jpg", ¶ms, kARGB_4444_SkColorType); 164 } 165 166 DEF_SIMPLE_GM(deferred_texture_image_medium_encoded, canvas, 512 + 512 + 30, 1110) { 167 sk_sp<SkImage> encodedImage = GetResourceAsImage("mandrill_512.png"); 168 if (!encodedImage) { 169 SkDebugf("\nCould not load resource.\n"); 170 return; 171 } 172 173 auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), 174 kMedium_SkFilterQuality, 0); 175 DrawDeferredTextureImageMipMapTree(canvas, encodedImage.get(), ¶ms, kN32_SkColorType); 176 } 177 178 DEF_SIMPLE_GM(deferred_texture_image_medium_decoded, canvas, 512 + 512 + 30, 1110) { 179 SkBitmap bitmap; 180 if (!GetResourceAsBitmap("mandrill_512.png", &bitmap)) { 181 SkDebugf("\nCould not decode resource.\n"); 182 return; 183 } 184 sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap); 185 186 auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), 187 kMedium_SkFilterQuality, 0); 188 DrawDeferredTextureImageMipMapTree(canvas, decodedImage.get(), ¶ms, kN32_SkColorType); 189 } 190 191 DEF_SIMPLE_GM(deferred_texture_image_high, canvas, 512 + 512 + 30, 512 + 20) { 192 auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(1.f, 1.f), 193 kHigh_SkFilterQuality, 0); 194 DrawDeferredTextureImageData(canvas, "mandrill_512.png", ¶ms, kN32_SkColorType); 195 } 196 197 DEF_SIMPLE_GM(deferred_texture_image_medium_encoded_indexed, canvas, 128 + 128 + 30, 340) { 198 sk_sp<SkImage> encodedImage = GetResourceAsImage("color_wheel.gif"); 199 if (!encodedImage) { 200 SkDebugf("\nCould not load resource.\n"); 201 return; 202 } 203 204 auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), 205 kMedium_SkFilterQuality, 0); 206 DrawDeferredTextureImageMipMapTree(canvas, encodedImage.get(), ¶ms, kN32_SkColorType); 207 } 208 209 DEF_SIMPLE_GM(deferred_texture_image_medium_decoded_indexed, canvas, 128 + 128 + 30, 340) { 210 SkBitmap bitmap; 211 if (!GetResourceAsBitmap("color_wheel.gif", &bitmap)) { 212 SkDebugf("\nCould not decode resource.\n"); 213 return; 214 } 215 sk_sp<SkImage> decodedImage = SkImage::MakeFromBitmap(bitmap); 216 217 auto params = SkImage::DeferredTextureImageUsageParams(SkMatrix::MakeScale(0.25f, 0.25f), 218 kMedium_SkFilterQuality, 0); 219 DrawDeferredTextureImageMipMapTree(canvas, decodedImage.get(), ¶ms, kN32_SkColorType); 220 } 221 222 #endif 223