Home | History | Annotate | Download | only in gm
      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", &params, 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", &params, 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", &params, 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(), &params, 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(), &params, 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", &params, 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(), &params, 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(), &params, kN32_SkColorType);
    220 }
    221 
    222 #endif
    223