1909d3791f53eae590314992aad82c71fb45e9164Matt Sarett/* 2909d3791f53eae590314992aad82c71fb45e9164Matt Sarett * Copyright 2016 Google Inc. 3909d3791f53eae590314992aad82c71fb45e9164Matt Sarett * 4909d3791f53eae590314992aad82c71fb45e9164Matt Sarett * Use of this source code is governed by a BSD-style license that can be 5909d3791f53eae590314992aad82c71fb45e9164Matt Sarett * found in the LICENSE file. 6909d3791f53eae590314992aad82c71fb45e9164Matt Sarett */ 7909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 8909d3791f53eae590314992aad82c71fb45e9164Matt Sarett#include "gm.h" 9909d3791f53eae590314992aad82c71fb45e9164Matt Sarett#include "Resources.h" 10909d3791f53eae590314992aad82c71fb45e9164Matt Sarett#include "SkCodec.h" 11909d3791f53eae590314992aad82c71fb45e9164Matt Sarett#include "SkColorSpace.h" 12b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman#include "SkColorSpaceXform.h" 13b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman#include "SkColorSpaceXformPriv.h" 14909d3791f53eae590314992aad82c71fb45e9164Matt Sarett#include "SkHalf.h" 15909d3791f53eae590314992aad82c71fb45e9164Matt Sarett#include "SkImage.h" 167fcfb621998648ba018e3b89e2cab3135bd46a1fMike Reed#include "SkImageInfoPriv.h" 1734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett#include "SkPictureRecorder.h" 18909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 19909d3791f53eae590314992aad82c71fb45e9164Matt Sarettstatic void clamp_if_necessary(const SkImageInfo& info, void* pixels) { 20909d3791f53eae590314992aad82c71fb45e9164Matt Sarett if (kRGBA_F16_SkColorType != info.colorType()) { 21909d3791f53eae590314992aad82c71fb45e9164Matt Sarett return; 22909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 23909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 24909d3791f53eae590314992aad82c71fb45e9164Matt Sarett for (int y = 0; y < info.height(); y++) { 25909d3791f53eae590314992aad82c71fb45e9164Matt Sarett for (int x = 0; x < info.width(); x++) { 26909d3791f53eae590314992aad82c71fb45e9164Matt Sarett uint64_t pixel = ((uint64_t*) pixels)[y * info.width() + x]; 27909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 28909d3791f53eae590314992aad82c71fb45e9164Matt Sarett Sk4f rgba = SkHalfToFloat_finite_ftz(pixel); 29909d3791f53eae590314992aad82c71fb45e9164Matt Sarett if (kUnpremul_SkAlphaType == info.alphaType()) { 30909d3791f53eae590314992aad82c71fb45e9164Matt Sarett rgba = Sk4f::Max(0.0f, Sk4f::Min(rgba, 1.0f)); 31909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } else { 32909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkASSERT(kPremul_SkAlphaType == info.alphaType()); 33909d3791f53eae590314992aad82c71fb45e9164Matt Sarett rgba = Sk4f::Max(0.0f, Sk4f::Min(rgba, rgba[3])); 34909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 35909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkFloatToHalf_finite_ftz(rgba).store(&pixel); 36909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 37909d3791f53eae590314992aad82c71fb45e9164Matt Sarett ((uint64_t*) pixels)[y * info.width() + x] = pixel; 38909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 39909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 40909d3791f53eae590314992aad82c71fb45e9164Matt Sarett} 41909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 42909d3791f53eae590314992aad82c71fb45e9164Matt Sarettsk_sp<SkColorSpace> fix_for_colortype(SkColorSpace* colorSpace, SkColorType colorType) { 43909d3791f53eae590314992aad82c71fb45e9164Matt Sarett if (kRGBA_F16_SkColorType == colorType) { 4436703d9d368050a20764b5336534bd718fd00a6eBrian Osman return colorSpace->makeLinearGamma(); 45909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 46909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 47909d3791f53eae590314992aad82c71fb45e9164Matt Sarett return sk_ref_sp(colorSpace); 48909d3791f53eae590314992aad82c71fb45e9164Matt Sarett} 49909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 50909d3791f53eae590314992aad82c71fb45e9164Matt Sarettstatic const int kWidth = 64; 51909d3791f53eae590314992aad82c71fb45e9164Matt Sarettstatic const int kHeight = 64; 52909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 53b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osmanstatic sk_sp<SkImage> make_raster_image(SkColorType colorType) { 54c465d13e6fca5e171bde45d35b2dd43117f4702eHal Canary std::unique_ptr<SkStream> stream(GetResourceAsStream("images/google_chrome.ico")); 55ede7bac43fbc69b9fdf1c178890ba6353f5bb140Mike Reed std::unique_ptr<SkCodec> codec = SkCodec::MakeFromStream(std::move(stream)); 56909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 57909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkBitmap bitmap; 58909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkImageInfo info = codec->getInfo().makeWH(kWidth, kHeight) 59909d3791f53eae590314992aad82c71fb45e9164Matt Sarett .makeColorType(colorType) 60b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman .makeAlphaType(kPremul_SkAlphaType) 61909d3791f53eae590314992aad82c71fb45e9164Matt Sarett .makeColorSpace(fix_for_colortype(codec->getInfo().colorSpace(), colorType)); 62909d3791f53eae590314992aad82c71fb45e9164Matt Sarett bitmap.allocPixels(info); 63909d3791f53eae590314992aad82c71fb45e9164Matt Sarett codec->getPixels(info, bitmap.getPixels(), bitmap.rowBytes()); 64909d3791f53eae590314992aad82c71fb45e9164Matt Sarett bitmap.setImmutable(); 65909d3791f53eae590314992aad82c71fb45e9164Matt Sarett return SkImage::MakeFromBitmap(bitmap); 66909d3791f53eae590314992aad82c71fb45e9164Matt Sarett} 67909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 6834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettstatic sk_sp<SkImage> make_codec_image() { 69c465d13e6fca5e171bde45d35b2dd43117f4702eHal Canary sk_sp<SkData> encoded = GetResourceAsData("images/randPixels.png"); 7034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett return SkImage::MakeFromEncoded(encoded); 7134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett} 7234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 7334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettstatic void draw_contents(SkCanvas* canvas) { 7434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkPaint paint; 7534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett paint.setStyle(SkPaint::kStroke_Style); 7634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett paint.setStrokeWidth(20); 7734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett paint.setColor(0xFF800000); 7834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->drawCircle(40, 40, 35, paint); 7934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett paint.setColor(0xFF008000); 8034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->drawCircle(50, 50, 35, paint); 8134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett paint.setColor(0xFF000080); 8234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->drawCircle(60, 60, 35, paint); 8334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett} 8434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 859df70bb74db8294283e8d2d8e20c95d290d2a34dMatt Sarettstatic sk_sp<SkImage> make_picture_image() { 8634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkPictureRecorder recorder; 8734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett draw_contents(recorder.beginRecording(SkRect::MakeIWH(kWidth, kHeight))); 8834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), 8934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkISize::Make(kWidth, kHeight), nullptr, nullptr, 9034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkImage::BitDepth::kU8, 9177a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett SkColorSpace::MakeSRGB()); 9234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett} 9334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 94733340a6997762dc2fe5048cfe5af33bf8293d93Matt Sarettstatic sk_sp<SkColorSpace> make_parametric_transfer_fn(const SkColorSpacePrimaries& primaries) { 95578f52c6cf6372b88a88a05dee0efc5b67aa9a9cMatt Sarett SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor); 96909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkAssertResult(primaries.toXYZD50(&toXYZD50)); 97733340a6997762dc2fe5048cfe5af33bf8293d93Matt Sarett SkColorSpaceTransferFn fn; 98733340a6997762dc2fe5048cfe5af33bf8293d93Matt Sarett fn.fA = 1.f; fn.fB = 0.f; fn.fC = 0.f; fn.fD = 0.f; fn.fE = 0.f; fn.fF = 0.f; fn.fG = 1.8f; 99733340a6997762dc2fe5048cfe5af33bf8293d93Matt Sarett return SkColorSpace::MakeRGB(fn, toXYZD50); 100909d3791f53eae590314992aad82c71fb45e9164Matt Sarett} 101909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 102909d3791f53eae590314992aad82c71fb45e9164Matt Sarettstatic sk_sp<SkColorSpace> make_wide_gamut() { 103909d3791f53eae590314992aad82c71fb45e9164Matt Sarett // ProPhoto 104909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkColorSpacePrimaries primaries; 105909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fRX = 0.7347f; 106909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fRY = 0.2653f; 107909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fGX = 0.1596f; 108909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fGY = 0.8404f; 109909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fBX = 0.0366f; 110909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fBY = 0.0001f; 111909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fWX = 0.34567f; 112909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fWY = 0.35850f; 113733340a6997762dc2fe5048cfe5af33bf8293d93Matt Sarett return make_parametric_transfer_fn(primaries); 114909d3791f53eae590314992aad82c71fb45e9164Matt Sarett} 115909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 116909d3791f53eae590314992aad82c71fb45e9164Matt Sarettstatic sk_sp<SkColorSpace> make_small_gamut() { 117909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkColorSpacePrimaries primaries; 118909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fRX = 0.50f; 119909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fRY = 0.33f; 120909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fGX = 0.30f; 121909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fGY = 0.50f; 122909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fBX = 0.25f; 123909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fBY = 0.16f; 124909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fWX = 0.3127f; 125909d3791f53eae590314992aad82c71fb45e9164Matt Sarett primaries.fWY = 0.3290f; 126733340a6997762dc2fe5048cfe5af33bf8293d93Matt Sarett return make_parametric_transfer_fn(primaries); 127909d3791f53eae590314992aad82c71fb45e9164Matt Sarett} 128909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 129909d3791f53eae590314992aad82c71fb45e9164Matt Sarettstatic void draw_image(SkCanvas* canvas, SkImage* image, SkColorType dstColorType, 13034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkAlphaType dstAlphaType, sk_sp<SkColorSpace> dstColorSpace, 13134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkImage::CachingHint hint) { 132909d3791f53eae590314992aad82c71fb45e9164Matt Sarett size_t rowBytes = image->width() * SkColorTypeBytesPerPixel(dstColorType); 133909d3791f53eae590314992aad82c71fb45e9164Matt Sarett sk_sp<SkData> data = SkData::MakeUninitialized(rowBytes * image->height()); 134909d3791f53eae590314992aad82c71fb45e9164Matt Sarett dstColorSpace = fix_for_colortype(dstColorSpace.get(), dstColorType); 135909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkImageInfo dstInfo = SkImageInfo::Make(image->width(), image->height(), dstColorType, 136909d3791f53eae590314992aad82c71fb45e9164Matt Sarett dstAlphaType, dstColorSpace); 13789150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman if (!image->readPixels(dstInfo, data->writable_data(), rowBytes, 0, 0, hint)) { 13889150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman memset(data->writable_data(), 0, rowBytes * image->height()); 13989150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman } 140909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 141b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman // SkImage must be premul, so manually premul the data if we unpremul'd during readPixels 142b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman if (kUnpremul_SkAlphaType == dstAlphaType) { 143b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman auto xform = SkColorSpaceXform::New(dstColorSpace.get(), dstColorSpace.get()); 144b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman if (!xform->apply(select_xform_format(dstColorType), data->writable_data(), 145b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman select_xform_format(dstColorType), data->data(), 146b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman image->width() * image->height(), kPremul_SkAlphaType)) { 147b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman memset(data->writable_data(), 0, rowBytes * image->height()); 148b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman } 149b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman dstInfo = dstInfo.makeAlphaType(kPremul_SkAlphaType); 150b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman } 151b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman 152909d3791f53eae590314992aad82c71fb45e9164Matt Sarett // readPixels() does not always clamp F16. The drawing code expects pixels in the 0-1 range. 153909d3791f53eae590314992aad82c71fb45e9164Matt Sarett clamp_if_necessary(dstInfo, data->writable_data()); 154909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 155909d3791f53eae590314992aad82c71fb45e9164Matt Sarett // Now that we have called readPixels(), dump the raw pixels into an srgb image. 156909d3791f53eae590314992aad82c71fb45e9164Matt Sarett sk_sp<SkColorSpace> srgb = fix_for_colortype( 15777a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett SkColorSpace::MakeSRGB().get(), dstColorType); 158909d3791f53eae590314992aad82c71fb45e9164Matt Sarett sk_sp<SkImage> raw = SkImage::MakeRasterData(dstInfo.makeColorSpace(srgb), data, rowBytes); 159909d3791f53eae590314992aad82c71fb45e9164Matt Sarett canvas->drawImage(raw.get(), 0.0f, 0.0f, nullptr); 160909d3791f53eae590314992aad82c71fb45e9164Matt Sarett} 161909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 162909d3791f53eae590314992aad82c71fb45e9164Matt Sarettclass ReadPixelsGM : public skiagm::GM { 163909d3791f53eae590314992aad82c71fb45e9164Matt Sarettpublic: 164909d3791f53eae590314992aad82c71fb45e9164Matt Sarett ReadPixelsGM() {} 165909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 166909d3791f53eae590314992aad82c71fb45e9164Matt Sarettprotected: 167909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkString onShortName() override { 168909d3791f53eae590314992aad82c71fb45e9164Matt Sarett return SkString("readpixels"); 169909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 170909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 171909d3791f53eae590314992aad82c71fb45e9164Matt Sarett SkISize onISize() override { 172b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman return SkISize::Make(6 * kWidth, 9 * kHeight); 173909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 174909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 175909d3791f53eae590314992aad82c71fb45e9164Matt Sarett void onDraw(SkCanvas* canvas) override { 176909d3791f53eae590314992aad82c71fb45e9164Matt Sarett if (!canvas->imageInfo().colorSpace()) { 177909d3791f53eae590314992aad82c71fb45e9164Matt Sarett // This gm is only interesting in color correct modes. 178909d3791f53eae590314992aad82c71fb45e9164Matt Sarett return; 179909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 180909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 181909d3791f53eae590314992aad82c71fb45e9164Matt Sarett const SkAlphaType alphaTypes[] = { 182909d3791f53eae590314992aad82c71fb45e9164Matt Sarett kUnpremul_SkAlphaType, 183909d3791f53eae590314992aad82c71fb45e9164Matt Sarett kPremul_SkAlphaType, 184909d3791f53eae590314992aad82c71fb45e9164Matt Sarett }; 185909d3791f53eae590314992aad82c71fb45e9164Matt Sarett const SkColorType colorTypes[] = { 186909d3791f53eae590314992aad82c71fb45e9164Matt Sarett kRGBA_8888_SkColorType, 187909d3791f53eae590314992aad82c71fb45e9164Matt Sarett kBGRA_8888_SkColorType, 188909d3791f53eae590314992aad82c71fb45e9164Matt Sarett kRGBA_F16_SkColorType, 189909d3791f53eae590314992aad82c71fb45e9164Matt Sarett }; 190909d3791f53eae590314992aad82c71fb45e9164Matt Sarett const sk_sp<SkColorSpace> colorSpaces[] = { 191909d3791f53eae590314992aad82c71fb45e9164Matt Sarett make_wide_gamut(), 19277a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett SkColorSpace::MakeSRGB(), 193909d3791f53eae590314992aad82c71fb45e9164Matt Sarett make_small_gamut(), 194909d3791f53eae590314992aad82c71fb45e9164Matt Sarett }; 195909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 196909d3791f53eae590314992aad82c71fb45e9164Matt Sarett for (sk_sp<SkColorSpace> dstColorSpace : colorSpaces) { 197909d3791f53eae590314992aad82c71fb45e9164Matt Sarett for (SkColorType srcColorType : colorTypes) { 198b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman canvas->save(); 199b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman sk_sp<SkImage> image = make_raster_image(srcColorType); 20089150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman if (GrContext* context = canvas->getGrContext()) { 20189150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman image = image->makeTextureImage(context, canvas->imageInfo().colorSpace()); 20289150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman } 20389150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman if (image) { 20489150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman for (SkColorType dstColorType : colorTypes) { 20589150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman for (SkAlphaType dstAlphaType : alphaTypes) { 20689150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman draw_image(canvas, image.get(), dstColorType, dstAlphaType, 20789150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman dstColorSpace, SkImage::kAllow_CachingHint); 20889150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman canvas->translate((float)kWidth, 0.0f); 20989150582643f1ef4893a0cdeaadf5886e5cde76dBrian Osman } 210909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 211909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 212b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman canvas->restore(); 213b1168a7c9a360bf80b447e2e399bdc5721d5152eBrian Osman canvas->translate(0.0f, (float) kHeight); 214909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 215909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 216909d3791f53eae590314992aad82c71fb45e9164Matt Sarett } 217909d3791f53eae590314992aad82c71fb45e9164Matt Sarett 218909d3791f53eae590314992aad82c71fb45e9164Matt Sarettprivate: 219909d3791f53eae590314992aad82c71fb45e9164Matt Sarett typedef skiagm::GM INHERITED; 220909d3791f53eae590314992aad82c71fb45e9164Matt Sarett}; 221909d3791f53eae590314992aad82c71fb45e9164Matt SarettDEF_GM( return new ReadPixelsGM; ) 22234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 22334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettclass ReadPixelsCodecGM : public skiagm::GM { 22434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettpublic: 22534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett ReadPixelsCodecGM() {} 22634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 22734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettprotected: 22834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkString onShortName() override { 22934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett return SkString("readpixelscodec"); 23034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 23134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 23234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkISize onISize() override { 23334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett return SkISize::Make(3 * (kEncodedWidth + 1), 12 * (kEncodedHeight + 1)); 23434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 23534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 23634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett void onDraw(SkCanvas* canvas) override { 23734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett if (!canvas->imageInfo().colorSpace()) { 23834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett // This gm is only interesting in color correct modes. 23934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett return; 24034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 24134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 24234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const SkAlphaType alphaTypes[] = { 24334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kUnpremul_SkAlphaType, 24434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kPremul_SkAlphaType, 24534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 24634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const SkColorType colorTypes[] = { 24734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kRGBA_8888_SkColorType, 24834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kBGRA_8888_SkColorType, 24934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kRGBA_F16_SkColorType, 25034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 25134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const sk_sp<SkColorSpace> colorSpaces[] = { 25234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett make_wide_gamut(), 25377a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett SkColorSpace::MakeSRGB(), 25434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett make_small_gamut(), 25534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 25634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const SkImage::CachingHint hints[] = { 25734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkImage::kAllow_CachingHint, 25834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkImage::kDisallow_CachingHint, 25934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 26034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 26134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett sk_sp<SkImage> image = make_codec_image(); 26234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (sk_sp<SkColorSpace> dstColorSpace : colorSpaces) { 26334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->save(); 26434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (SkColorType dstColorType : colorTypes) { 26534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (SkAlphaType dstAlphaType : alphaTypes) { 26634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (SkImage::CachingHint hint : hints) { 26734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett draw_image(canvas, image.get(), dstColorType, dstAlphaType, dstColorSpace, 26834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett hint); 26934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->translate(0.0f, (float) kEncodedHeight + 1); 27034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 27134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 27234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 27334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->restore(); 27434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->translate((float) kEncodedWidth + 1, 0.0f); 27534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 27634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 27734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 27834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettprivate: 27934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett static const int kEncodedWidth = 8; 28034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett static const int kEncodedHeight = 8; 28134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 28234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett typedef skiagm::GM INHERITED; 28334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett}; 28434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt SarettDEF_GM( return new ReadPixelsCodecGM; ) 28534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 28634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettclass ReadPixelsPictureGM : public skiagm::GM { 28734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettpublic: 28834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett ReadPixelsPictureGM() {} 28934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 29034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettprotected: 29134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkString onShortName() override { 29234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett return SkString("readpixelspicture"); 29334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 29434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 29534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkISize onISize() override { 29634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett return SkISize::Make(3 * kWidth, 12 * kHeight); 29734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 29834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 29934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett void onDraw(SkCanvas* canvas) override { 30034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett if (!canvas->imageInfo().colorSpace()) { 30134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett // This gm is only interesting in color correct modes. 30234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett return; 30334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 30434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 30534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const sk_sp<SkImage> images[] = { 3069df70bb74db8294283e8d2d8e20c95d290d2a34dMatt Sarett make_picture_image(), 30734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 30834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const SkAlphaType alphaTypes[] = { 30934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kUnpremul_SkAlphaType, 31034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kPremul_SkAlphaType, 31134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 31234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const SkColorType colorTypes[] = { 31334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kRGBA_8888_SkColorType, 31434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kBGRA_8888_SkColorType, 31534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett kRGBA_F16_SkColorType, 31634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 31734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const sk_sp<SkColorSpace> colorSpaces[] = { 31834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett make_wide_gamut(), 31977a7a1b57c16c97f056c1e50c03bdc954947778cMatt Sarett SkColorSpace::MakeSRGB(), 32034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett make_small_gamut(), 32134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 32234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett const SkImage::CachingHint hints[] = { 32334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkImage::kAllow_CachingHint, 32434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett SkImage::kDisallow_CachingHint, 32534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett }; 32634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 32734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (sk_sp<SkImage> image : images) { 32834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (sk_sp<SkColorSpace> dstColorSpace : colorSpaces) { 32934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->save(); 33034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (SkColorType dstColorType : colorTypes) { 33134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (SkAlphaType dstAlphaType : alphaTypes) { 33234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett for (SkImage::CachingHint hint : hints) { 33334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett draw_image(canvas, image.get(), dstColorType, dstAlphaType, 33434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett dstColorSpace, hint); 33534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->translate(0.0f, (float) kHeight); 33634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 33734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 33834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 33934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->restore(); 34034855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett canvas->translate((float) kWidth, 0.0f); 34134855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 34234855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 34334855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett } 34434855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 34534855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarettprivate: 34634855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett 34734855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett typedef skiagm::GM INHERITED; 34834855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt Sarett}; 34934855f9e1c40bf91d2bdbd34b32868eb06327c9fMatt SarettDEF_GM( return new ReadPixelsPictureGM; ) 350