blob: 45064e15d506f9894a4aaec221f31276d744d160 [file] [log] [blame]
robertphillipsb6c65e92016-02-04 10:52:42 -08001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkBitmap.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkImage.h"
11#include "include/core/SkPixmap.h"
12#include "include/core/SkSurface.h"
Robert Phillips6d344c32020-07-06 10:56:46 -040013#include "include/gpu/GrBackendSurface.h"
14#include "include/gpu/GrDirectContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/core/SkAutoPixmapStorage.h"
16#include "src/core/SkSpecialImage.h"
17#include "src/core/SkSpecialSurface.h"
Greg Daniel6f5441a2020-01-28 17:02:49 -050018#include "src/gpu/GrBitmapTextureMaker.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "src/gpu/GrContextPriv.h"
20#include "src/gpu/GrProxyProvider.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040021#include "src/gpu/GrSurfaceProxy.h"
22#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/SkGr.h"
Robert Phillips6d344c32020-07-06 10:56:46 -040024#include "tests/Test.h"
robertphillipsb6c65e92016-02-04 10:52:42 -080025
26// This test creates backing resources exactly sized to [kFullSize x kFullSize].
27// It then wraps them in an SkSpecialImage with only the center (red) region being active.
28// It then draws the SkSpecialImage to a full sized (all blue) canvas and checks that none
29// of the inactive (green) region leaked out.
30
31static const int kSmallerSize = 10;
32static const int kPad = 3;
33static const int kFullSize = kSmallerSize + 2 * kPad;
34
35// Create a bitmap with red in the center and green around it
36static SkBitmap create_bm() {
Robert Phillips40b05c32019-09-20 12:40:55 -040037 SkImageInfo ii = SkImageInfo::Make(kFullSize, kFullSize, kRGBA_8888_SkColorType,
38 kPremul_SkAlphaType);
39
robertphillipsb6c65e92016-02-04 10:52:42 -080040 SkBitmap bm;
Robert Phillips40b05c32019-09-20 12:40:55 -040041 bm.allocPixels(ii);
robertphillipsb6c65e92016-02-04 10:52:42 -080042
43 SkCanvas temp(bm);
44
45 temp.clear(SK_ColorGREEN);
46 SkPaint p;
47 p.setColor(SK_ColorRED);
48 p.setAntiAlias(false);
49
50 temp.drawRect(SkRect::MakeXYWH(SkIntToScalar(kPad), SkIntToScalar(kPad),
halcanary9d524f22016-03-29 09:03:52 -070051 SkIntToScalar(kSmallerSize), SkIntToScalar(kSmallerSize)),
robertphillipsb6c65e92016-02-04 10:52:42 -080052 p);
53
Greg Daniel6f5441a2020-01-28 17:02:49 -050054 bm.setImmutable();
robertphillipsb6c65e92016-02-04 10:52:42 -080055 return bm;
56}
57
58// Basic test of the SkSpecialImage public API (e.g., peekTexture, peekPixels & draw)
robertphillips37bd7c32016-03-17 14:31:39 -070059static void test_image(const sk_sp<SkSpecialImage>& img, skiatest::Reporter* reporter,
Michael Ludwigb4580352019-06-21 16:01:42 -040060 GrContext* context, bool isGPUBacked) {
robertphillips3e302272016-04-20 11:48:36 -070061 const SkIRect subset = img->subset();
Michael Ludwigb4580352019-06-21 16:01:42 -040062 REPORTER_ASSERT(reporter, kPad == subset.left());
63 REPORTER_ASSERT(reporter, kPad == subset.top());
robertphillipsb6c65e92016-02-04 10:52:42 -080064 REPORTER_ASSERT(reporter, kSmallerSize == subset.width());
65 REPORTER_ASSERT(reporter, kSmallerSize == subset.height());
66
67 //--------------
Robert Phillips2c6d2bf2017-02-21 10:19:29 -050068 // Test that isTextureBacked reports the correct backing type
Robert Phillips6de99042017-01-31 11:31:39 -050069 REPORTER_ASSERT(reporter, isGPUBacked == img->isTextureBacked());
robertphillips64612512016-04-08 12:10:42 -070070
robertphillips64612512016-04-08 12:10:42 -070071 //--------------
Greg Daniel37c127f2020-02-05 10:37:27 -050072 // Test view - as long as there is a context this should succeed
robertphillips64612512016-04-08 12:10:42 -070073 if (context) {
Greg Daniel37c127f2020-02-05 10:37:27 -050074 GrSurfaceProxyView view = img->view(context);
Greg Daniel83547172020-01-29 11:11:03 -050075 REPORTER_ASSERT(reporter, view.asTextureProxy());
robertphillips64612512016-04-08 12:10:42 -070076 }
robertphillipsb6c65e92016-02-04 10:52:42 -080077
78 //--------------
Brian Osmane7ad8c02020-06-22 14:51:22 -040079 // Test getROPixels - this only works for raster-backed special images
80 if (!img->isTextureBacked()) {
81 SkBitmap bitmap;
82 REPORTER_ASSERT(reporter, img->getROPixels(&bitmap));
83 REPORTER_ASSERT(reporter, kSmallerSize == bitmap.width());
84 REPORTER_ASSERT(reporter, kSmallerSize == bitmap.height());
85 }
robertphillipsb6c65e92016-02-04 10:52:42 -080086
87 //--------------
robertphillipsb4bd11e2016-03-21 13:44:18 -070088 // Test that draw restricts itself to the subset
Michael Ludwig03f9ca32019-08-14 14:35:15 -040089 sk_sp<SkSpecialSurface> surf(img->makeSurface(kN32_SkColorType, img->getColorSpace(),
90 SkISize::Make(kFullSize, kFullSize),
Matt Sarettcb6266b2017-01-17 10:48:53 -050091 kPremul_SkAlphaType));
robertphillipsb6c65e92016-02-04 10:52:42 -080092
93 SkCanvas* canvas = surf->getCanvas();
94
95 canvas->clear(SK_ColorBLUE);
robertphillipse8c34972016-02-16 12:09:36 -080096 img->draw(canvas, SkIntToScalar(kPad), SkIntToScalar(kPad), nullptr);
robertphillipsb6c65e92016-02-04 10:52:42 -080097
98 SkBitmap bm;
Matt Sarettcb6266b2017-01-17 10:48:53 -050099 bm.allocN32Pixels(kFullSize, kFullSize, false);
robertphillipsb6c65e92016-02-04 10:52:42 -0800100
101 bool result = canvas->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), 0, 0);
102 SkASSERT_RELEASE(result);
103
104 // Only the center (red) portion should've been drawn into the canvas
105 REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kPad-1, kPad-1));
106 REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kPad, kPad));
107 REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kSmallerSize+kPad-1,
108 kSmallerSize+kPad-1));
109 REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kSmallerSize+kPad,
110 kSmallerSize+kPad));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700111
112 //--------------
Robert Phillipsa5fdc972017-02-18 16:58:09 -0500113 // Test that asImage & makeTightSurface return appropriately sized objects
robertphillipsb4bd11e2016-03-21 13:44:18 -0700114 // of the correct backing type
115 SkIRect newSubset = SkIRect::MakeWH(subset.width(), subset.height());
116 {
Robert Phillipsa5fdc972017-02-18 16:58:09 -0500117 sk_sp<SkImage> tightImg(img->asImage(&newSubset));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700118
119 REPORTER_ASSERT(reporter, tightImg->width() == subset.width());
120 REPORTER_ASSERT(reporter, tightImg->height() == subset.height());
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400121 REPORTER_ASSERT(reporter, isGPUBacked == tightImg->isTextureBacked());
robertphillipsb4bd11e2016-03-21 13:44:18 -0700122 SkPixmap tmpPixmap;
Robert Phillips6de99042017-01-31 11:31:39 -0500123 REPORTER_ASSERT(reporter, isGPUBacked != !!tightImg->peekPixels(&tmpPixmap));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700124 }
125 {
Michael Ludwig03f9ca32019-08-14 14:35:15 -0400126 sk_sp<SkSurface> tightSurf(img->makeTightSurface(kN32_SkColorType, img->getColorSpace(),
127 subset.size()));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700128
129 REPORTER_ASSERT(reporter, tightSurf->width() == subset.width());
130 REPORTER_ASSERT(reporter, tightSurf->height() == subset.height());
Robert Phillips8caf85f2018-04-05 09:30:38 -0400131 GrBackendTexture backendTex = tightSurf->getBackendTexture(
132 SkSurface::kDiscardWrite_BackendHandleAccess);
133 REPORTER_ASSERT(reporter, isGPUBacked == backendTex.isValid());
robertphillipsb4bd11e2016-03-21 13:44:18 -0700134 SkPixmap tmpPixmap;
Robert Phillips6de99042017-01-31 11:31:39 -0500135 REPORTER_ASSERT(reporter, isGPUBacked != !!tightSurf->peekPixels(&tmpPixmap));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700136 }
robertphillipsb6c65e92016-02-04 10:52:42 -0800137}
138
139DEF_TEST(SpecialImage_Raster, reporter) {
140 SkBitmap bm = create_bm();
141
robertphillips37bd7c32016-03-17 14:31:39 -0700142 sk_sp<SkSpecialImage> fullSImage(SkSpecialImage::MakeFromRaster(
robertphillipsc5035e72016-03-17 06:58:39 -0700143 SkIRect::MakeWH(kFullSize, kFullSize),
144 bm));
145
robertphillipsb6c65e92016-02-04 10:52:42 -0800146 const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
147
robertphillipsc5035e72016-03-17 06:58:39 -0700148 {
robertphillips3e302272016-04-20 11:48:36 -0700149 sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeFromRaster(subset, bm));
Michael Ludwigb4580352019-06-21 16:01:42 -0400150 test_image(subSImg1, reporter, nullptr, false);
robertphillipsc5035e72016-03-17 06:58:39 -0700151 }
152
153 {
robertphillips37bd7c32016-03-17 14:31:39 -0700154 sk_sp<SkSpecialImage> subSImg2(fullSImage->makeSubset(subset));
Michael Ludwigb4580352019-06-21 16:01:42 -0400155 test_image(subSImg2, reporter, nullptr, false);
robertphillipsc5035e72016-03-17 06:58:39 -0700156 }
robertphillipsb6c65e92016-02-04 10:52:42 -0800157}
158
Brian Osmanb9c49782018-10-12 12:01:22 -0400159static void test_specialimage_image(skiatest::Reporter* reporter) {
robertphillipsb6c65e92016-02-04 10:52:42 -0800160 SkBitmap bm = create_bm();
161
reed9ce9d672016-03-17 10:51:11 -0700162 sk_sp<SkImage> fullImage(SkImage::MakeFromBitmap(bm));
robertphillipsb6c65e92016-02-04 10:52:42 -0800163
robertphillips37bd7c32016-03-17 14:31:39 -0700164 sk_sp<SkSpecialImage> fullSImage(SkSpecialImage::MakeFromImage(
Robert Phillips27467652019-01-10 16:34:22 -0500165 nullptr,
robertphillipsc5035e72016-03-17 06:58:39 -0700166 SkIRect::MakeWH(kFullSize, kFullSize),
Brian Osmanb9c49782018-10-12 12:01:22 -0400167 fullImage));
robertphillipsc5035e72016-03-17 06:58:39 -0700168
robertphillipsb6c65e92016-02-04 10:52:42 -0800169 const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
170
robertphillipsc5035e72016-03-17 06:58:39 -0700171 {
Robert Phillips27467652019-01-10 16:34:22 -0500172 sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeFromImage(nullptr, subset, fullImage));
Michael Ludwigb4580352019-06-21 16:01:42 -0400173 test_image(subSImg1, reporter, nullptr, false);
robertphillipsc5035e72016-03-17 06:58:39 -0700174 }
175
176 {
robertphillips37bd7c32016-03-17 14:31:39 -0700177 sk_sp<SkSpecialImage> subSImg2(fullSImage->makeSubset(subset));
Michael Ludwigb4580352019-06-21 16:01:42 -0400178 test_image(subSImg2, reporter, nullptr, false);
robertphillipsc5035e72016-03-17 06:58:39 -0700179 }
robertphillipsb6c65e92016-02-04 10:52:42 -0800180}
181
Brian Osman7992da32016-11-18 11:28:24 -0500182DEF_TEST(SpecialImage_Image_Legacy, reporter) {
Brian Osmanb9c49782018-10-12 12:01:22 -0400183 test_specialimage_image(reporter);
Brian Osman7992da32016-11-18 11:28:24 -0500184}
185
bsalomon68d91342016-04-12 09:59:58 -0700186DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400187 auto context = ctxInfo.directContext();
robertphillipsb6c65e92016-02-04 10:52:42 -0800188 SkBitmap bm = create_bm();
Brian Salomonbc074a62020-03-18 10:06:13 -0400189 GrBitmapTextureMaker maker(context, bm, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
Brian Salomonecbb0fb2020-02-28 18:07:32 -0500190 auto view = maker.view(GrMipMapped::kNo);
Greg Danielcc104db2020-02-03 14:17:08 -0500191 if (!view.proxy()) {
robertphillipsb6c65e92016-02-04 10:52:42 -0800192 return;
193 }
194
Brian Salomonecbb0fb2020-02-28 18:07:32 -0500195 sk_sp<SkSpecialImage> fullSImg(
196 SkSpecialImage::MakeDeferredFromGpu(context,
197 SkIRect::MakeWH(kFullSize, kFullSize),
198 kNeedNewImageUniqueID_SpecialImage,
199 view,
200 maker.colorType(),
201 nullptr));
robertphillipsc5035e72016-03-17 06:58:39 -0700202
robertphillipsb6c65e92016-02-04 10:52:42 -0800203 const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
204
robertphillipsc5035e72016-03-17 06:58:39 -0700205 {
Robert Phillips2c6d2bf2017-02-21 10:19:29 -0500206 sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeDeferredFromGpu(
Brian Salomonecbb0fb2020-02-28 18:07:32 -0500207 context,
208 subset,
209 kNeedNewImageUniqueID_SpecialImage,
210 std::move(view),
211 maker.colorType(),
212 nullptr));
Michael Ludwigb4580352019-06-21 16:01:42 -0400213 test_image(subSImg1, reporter, context, true);
robertphillipsc5035e72016-03-17 06:58:39 -0700214 }
215
216 {
robertphillips37bd7c32016-03-17 14:31:39 -0700217 sk_sp<SkSpecialImage> subSImg2(fullSImg->makeSubset(subset));
Michael Ludwigb4580352019-06-21 16:01:42 -0400218 test_image(subSImg2, reporter, context, true);
robertphillipsc5035e72016-03-17 06:58:39 -0700219 }
robertphillipsb6c65e92016-02-04 10:52:42 -0800220}