1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkImage.h" 11cb93a386Sopenharmony_ci#include "include/core/SkPixmap.h" 12cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 13cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h" 14cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 15cb93a386Sopenharmony_ci#include "src/core/SkAutoPixmapStorage.h" 16cb93a386Sopenharmony_ci#include "src/core/SkSpecialImage.h" 17cb93a386Sopenharmony_ci#include "src/core/SkSpecialSurface.h" 18cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 19cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 20cb93a386Sopenharmony_ci#include "src/gpu/GrSurfaceProxy.h" 21cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxy.h" 22cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h" 23cb93a386Sopenharmony_ci#include "tests/Test.h" 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ci// This test creates backing resources exactly sized to [kFullSize x kFullSize]. 26cb93a386Sopenharmony_ci// It then wraps them in an SkSpecialImage with only the center (red) region being active. 27cb93a386Sopenharmony_ci// It then draws the SkSpecialImage to a full sized (all blue) canvas and checks that none 28cb93a386Sopenharmony_ci// of the inactive (green) region leaked out. 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_cistatic const int kSmallerSize = 10; 31cb93a386Sopenharmony_cistatic const int kPad = 3; 32cb93a386Sopenharmony_cistatic const int kFullSize = kSmallerSize + 2 * kPad; 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci// Create a bitmap with red in the center and green around it 35cb93a386Sopenharmony_cistatic SkBitmap create_bm() { 36cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::Make(kFullSize, kFullSize, kRGBA_8888_SkColorType, 37cb93a386Sopenharmony_ci kPremul_SkAlphaType); 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci SkBitmap bm; 40cb93a386Sopenharmony_ci bm.allocPixels(ii); 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci SkCanvas temp(bm); 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci temp.clear(SK_ColorGREEN); 45cb93a386Sopenharmony_ci SkPaint p; 46cb93a386Sopenharmony_ci p.setColor(SK_ColorRED); 47cb93a386Sopenharmony_ci p.setAntiAlias(false); 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci temp.drawRect(SkRect::MakeXYWH(SkIntToScalar(kPad), SkIntToScalar(kPad), 50cb93a386Sopenharmony_ci SkIntToScalar(kSmallerSize), SkIntToScalar(kSmallerSize)), 51cb93a386Sopenharmony_ci p); 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci bm.setImmutable(); 54cb93a386Sopenharmony_ci return bm; 55cb93a386Sopenharmony_ci} 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci// Basic test of the SkSpecialImage public API (e.g., peekTexture, peekPixels & draw) 58cb93a386Sopenharmony_cistatic void test_image(const sk_sp<SkSpecialImage>& img, skiatest::Reporter* reporter, 59cb93a386Sopenharmony_ci GrRecordingContext* rContext, bool isGPUBacked) { 60cb93a386Sopenharmony_ci const SkIRect subset = img->subset(); 61cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, kPad == subset.left()); 62cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, kPad == subset.top()); 63cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, kSmallerSize == subset.width()); 64cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, kSmallerSize == subset.height()); 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci //-------------- 67cb93a386Sopenharmony_ci // Test that isTextureBacked reports the correct backing type 68cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, isGPUBacked == img->isTextureBacked()); 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci //-------------- 71cb93a386Sopenharmony_ci // Test view - as long as there is a context this should succeed 72cb93a386Sopenharmony_ci if (rContext) { 73cb93a386Sopenharmony_ci GrSurfaceProxyView view = img->view(rContext); 74cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, view.asTextureProxy()); 75cb93a386Sopenharmony_ci } 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ci //-------------- 78cb93a386Sopenharmony_ci // Test getROPixels - this only works for raster-backed special images 79cb93a386Sopenharmony_ci if (!img->isTextureBacked()) { 80cb93a386Sopenharmony_ci SkBitmap bitmap; 81cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, img->getROPixels(&bitmap)); 82cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, kSmallerSize == bitmap.width()); 83cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, kSmallerSize == bitmap.height()); 84cb93a386Sopenharmony_ci } 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci //-------------- 87cb93a386Sopenharmony_ci // Test that draw restricts itself to the subset 88cb93a386Sopenharmony_ci sk_sp<SkSpecialSurface> surf(img->makeSurface(kN32_SkColorType, img->getColorSpace(), 89cb93a386Sopenharmony_ci SkISize::Make(kFullSize, kFullSize), 90cb93a386Sopenharmony_ci kPremul_SkAlphaType, SkSurfaceProps())); 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci SkCanvas* canvas = surf->getCanvas(); 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci canvas->clear(SK_ColorBLUE); 95cb93a386Sopenharmony_ci img->draw(canvas, SkIntToScalar(kPad), SkIntToScalar(kPad)); 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci SkBitmap bm; 98cb93a386Sopenharmony_ci bm.allocN32Pixels(kFullSize, kFullSize, false); 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci bool result = canvas->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), 0, 0); 101cb93a386Sopenharmony_ci SkASSERT_RELEASE(result); 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci // Only the center (red) portion should've been drawn into the canvas 104cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kPad-1, kPad-1)); 105cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kPad, kPad)); 106cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kSmallerSize+kPad-1, 107cb93a386Sopenharmony_ci kSmallerSize+kPad-1)); 108cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kSmallerSize+kPad, 109cb93a386Sopenharmony_ci kSmallerSize+kPad)); 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci //-------------- 112cb93a386Sopenharmony_ci // Test that asImage & makeTightSurface return appropriately sized objects 113cb93a386Sopenharmony_ci // of the correct backing type 114cb93a386Sopenharmony_ci SkIRect newSubset = SkIRect::MakeWH(subset.width(), subset.height()); 115cb93a386Sopenharmony_ci { 116cb93a386Sopenharmony_ci sk_sp<SkImage> tightImg(img->asImage(&newSubset)); 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, tightImg->width() == subset.width()); 119cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, tightImg->height() == subset.height()); 120cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, isGPUBacked == tightImg->isTextureBacked()); 121cb93a386Sopenharmony_ci SkPixmap tmpPixmap; 122cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, isGPUBacked != !!tightImg->peekPixels(&tmpPixmap)); 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci { 125cb93a386Sopenharmony_ci sk_sp<SkSurface> tightSurf(img->makeTightSurface(kN32_SkColorType, img->getColorSpace(), 126cb93a386Sopenharmony_ci subset.size())); 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, tightSurf->width() == subset.width()); 129cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, tightSurf->height() == subset.height()); 130cb93a386Sopenharmony_ci GrBackendTexture backendTex = tightSurf->getBackendTexture( 131cb93a386Sopenharmony_ci SkSurface::kDiscardWrite_BackendHandleAccess); 132cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, isGPUBacked == backendTex.isValid()); 133cb93a386Sopenharmony_ci SkPixmap tmpPixmap; 134cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, isGPUBacked != !!tightSurf->peekPixels(&tmpPixmap)); 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci} 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ciDEF_TEST(SpecialImage_Raster, reporter) { 139cb93a386Sopenharmony_ci SkBitmap bm = create_bm(); 140cb93a386Sopenharmony_ci 141cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> fullSImage(SkSpecialImage::MakeFromRaster( 142cb93a386Sopenharmony_ci SkIRect::MakeWH(kFullSize, kFullSize), 143cb93a386Sopenharmony_ci bm, SkSurfaceProps())); 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize); 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci { 148cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeFromRaster(subset, bm, 149cb93a386Sopenharmony_ci SkSurfaceProps())); 150cb93a386Sopenharmony_ci test_image(subSImg1, reporter, nullptr, false); 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci { 154cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> subSImg2(fullSImage->makeSubset(subset)); 155cb93a386Sopenharmony_ci test_image(subSImg2, reporter, nullptr, false); 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci} 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_cistatic void test_specialimage_image(skiatest::Reporter* reporter) { 160cb93a386Sopenharmony_ci SkBitmap bm = create_bm(); 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_ci sk_sp<SkImage> fullImage(bm.asImage()); 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> fullSImage(SkSpecialImage::MakeFromImage( 165cb93a386Sopenharmony_ci nullptr, 166cb93a386Sopenharmony_ci SkIRect::MakeWH(kFullSize, kFullSize), 167cb93a386Sopenharmony_ci fullImage, 168cb93a386Sopenharmony_ci SkSurfaceProps())); 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize); 171cb93a386Sopenharmony_ci 172cb93a386Sopenharmony_ci { 173cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeFromImage(nullptr, subset, fullImage, 174cb93a386Sopenharmony_ci SkSurfaceProps())); 175cb93a386Sopenharmony_ci test_image(subSImg1, reporter, nullptr, false); 176cb93a386Sopenharmony_ci } 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_ci { 179cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> subSImg2(fullSImage->makeSubset(subset)); 180cb93a386Sopenharmony_ci test_image(subSImg2, reporter, nullptr, false); 181cb93a386Sopenharmony_ci } 182cb93a386Sopenharmony_ci} 183cb93a386Sopenharmony_ci 184cb93a386Sopenharmony_ciDEF_TEST(SpecialImage_Image_Legacy, reporter) { 185cb93a386Sopenharmony_ci test_specialimage_image(reporter); 186cb93a386Sopenharmony_ci} 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, ctxInfo) { 189cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 190cb93a386Sopenharmony_ci SkBitmap bm = create_bm(); 191cb93a386Sopenharmony_ci auto [view, ct] = GrMakeUncachedBitmapProxyView(context, bm); 192cb93a386Sopenharmony_ci if (!view) { 193cb93a386Sopenharmony_ci return; 194cb93a386Sopenharmony_ci } 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> fullSImg = 197cb93a386Sopenharmony_ci SkSpecialImage::MakeDeferredFromGpu(context, 198cb93a386Sopenharmony_ci SkIRect::MakeWH(kFullSize, kFullSize), 199cb93a386Sopenharmony_ci kNeedNewImageUniqueID_SpecialImage, 200cb93a386Sopenharmony_ci view, 201cb93a386Sopenharmony_ci ct, 202cb93a386Sopenharmony_ci nullptr, 203cb93a386Sopenharmony_ci SkSurfaceProps()); 204cb93a386Sopenharmony_ci 205cb93a386Sopenharmony_ci const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize); 206cb93a386Sopenharmony_ci 207cb93a386Sopenharmony_ci { 208cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> subSImg1 = SkSpecialImage::MakeDeferredFromGpu( 209cb93a386Sopenharmony_ci context, 210cb93a386Sopenharmony_ci subset, 211cb93a386Sopenharmony_ci kNeedNewImageUniqueID_SpecialImage, 212cb93a386Sopenharmony_ci std::move(view), 213cb93a386Sopenharmony_ci ct, 214cb93a386Sopenharmony_ci nullptr, 215cb93a386Sopenharmony_ci SkSurfaceProps()); 216cb93a386Sopenharmony_ci test_image(subSImg1, reporter, context, true); 217cb93a386Sopenharmony_ci } 218cb93a386Sopenharmony_ci 219cb93a386Sopenharmony_ci { 220cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> subSImg2 = fullSImg->makeSubset(subset); 221cb93a386Sopenharmony_ci test_image(subSImg2, reporter, context, true); 222cb93a386Sopenharmony_ci } 223cb93a386Sopenharmony_ci} 224