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