blob: 90f233a30420c636182d2d622931c4a0ccd1655c [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"
Adlai Hollera0693042020-10-14 11:23:11 -040018#include "src/gpu/GrDirectContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "src/gpu/GrProxyProvider.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040020#include "src/gpu/GrSurfaceProxy.h"
21#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050022#include "src/gpu/SkGr.h"
Robert Phillips6d344c32020-07-06 10:56:46 -040023#include "tests/Test.h"
robertphillipsb6c65e92016-02-04 10:52:42 -080024
25// This test creates backing resources exactly sized to [kFullSize x kFullSize].
26// It then wraps them in an SkSpecialImage with only the center (red) region being active.
27// It then draws the SkSpecialImage to a full sized (all blue) canvas and checks that none
28// of the inactive (green) region leaked out.
29
30static const int kSmallerSize = 10;
31static const int kPad = 3;
32static const int kFullSize = kSmallerSize + 2 * kPad;
33
34// Create a bitmap with red in the center and green around it
35static SkBitmap create_bm() {
Robert Phillips40b05c32019-09-20 12:40:55 -040036 SkImageInfo ii = SkImageInfo::Make(kFullSize, kFullSize, kRGBA_8888_SkColorType,
37 kPremul_SkAlphaType);
38
robertphillipsb6c65e92016-02-04 10:52:42 -080039 SkBitmap bm;
Robert Phillips40b05c32019-09-20 12:40:55 -040040 bm.allocPixels(ii);
robertphillipsb6c65e92016-02-04 10:52:42 -080041
42 SkCanvas temp(bm);
43
44 temp.clear(SK_ColorGREEN);
45 SkPaint p;
46 p.setColor(SK_ColorRED);
47 p.setAntiAlias(false);
48
49 temp.drawRect(SkRect::MakeXYWH(SkIntToScalar(kPad), SkIntToScalar(kPad),
halcanary9d524f22016-03-29 09:03:52 -070050 SkIntToScalar(kSmallerSize), SkIntToScalar(kSmallerSize)),
robertphillipsb6c65e92016-02-04 10:52:42 -080051 p);
52
Greg Daniel6f5441a2020-01-28 17:02:49 -050053 bm.setImmutable();
robertphillipsb6c65e92016-02-04 10:52:42 -080054 return bm;
55}
56
57// Basic test of the SkSpecialImage public API (e.g., peekTexture, peekPixels & draw)
robertphillips37bd7c32016-03-17 14:31:39 -070058static void test_image(const sk_sp<SkSpecialImage>& img, skiatest::Reporter* reporter,
Robert Phillipse94b4e12020-07-23 13:54:35 -040059 GrRecordingContext* rContext, bool isGPUBacked) {
robertphillips3e302272016-04-20 11:48:36 -070060 const SkIRect subset = img->subset();
Michael Ludwigb4580352019-06-21 16:01:42 -040061 REPORTER_ASSERT(reporter, kPad == subset.left());
62 REPORTER_ASSERT(reporter, kPad == subset.top());
robertphillipsb6c65e92016-02-04 10:52:42 -080063 REPORTER_ASSERT(reporter, kSmallerSize == subset.width());
64 REPORTER_ASSERT(reporter, kSmallerSize == subset.height());
65
66 //--------------
Robert Phillips2c6d2bf2017-02-21 10:19:29 -050067 // Test that isTextureBacked reports the correct backing type
Robert Phillips6de99042017-01-31 11:31:39 -050068 REPORTER_ASSERT(reporter, isGPUBacked == img->isTextureBacked());
robertphillips64612512016-04-08 12:10:42 -070069
robertphillips64612512016-04-08 12:10:42 -070070 //--------------
Greg Daniel37c127f2020-02-05 10:37:27 -050071 // Test view - as long as there is a context this should succeed
Robert Phillipse94b4e12020-07-23 13:54:35 -040072 if (rContext) {
73 GrSurfaceProxyView view = img->view(rContext);
Greg Daniel83547172020-01-29 11:11:03 -050074 REPORTER_ASSERT(reporter, view.asTextureProxy());
robertphillips64612512016-04-08 12:10:42 -070075 }
robertphillipsb6c65e92016-02-04 10:52:42 -080076
77 //--------------
Brian Osmane7ad8c02020-06-22 14:51:22 -040078 // Test getROPixels - this only works for raster-backed special images
79 if (!img->isTextureBacked()) {
80 SkBitmap bitmap;
81 REPORTER_ASSERT(reporter, img->getROPixels(&bitmap));
82 REPORTER_ASSERT(reporter, kSmallerSize == bitmap.width());
83 REPORTER_ASSERT(reporter, kSmallerSize == bitmap.height());
84 }
robertphillipsb6c65e92016-02-04 10:52:42 -080085
86 //--------------
robertphillipsb4bd11e2016-03-21 13:44:18 -070087 // Test that draw restricts itself to the subset
Michael Ludwig03f9ca32019-08-14 14:35:15 -040088 sk_sp<SkSpecialSurface> surf(img->makeSurface(kN32_SkColorType, img->getColorSpace(),
89 SkISize::Make(kFullSize, kFullSize),
Chris Daltonf5b87f92021-04-19 17:27:09 -060090 kPremul_SkAlphaType, SkSurfaceProps()));
robertphillipsb6c65e92016-02-04 10:52:42 -080091
92 SkCanvas* canvas = surf->getCanvas();
93
94 canvas->clear(SK_ColorBLUE);
Mike Reed9702fc62021-01-22 21:44:57 -050095 img->draw(canvas, SkIntToScalar(kPad), SkIntToScalar(kPad));
robertphillipsb6c65e92016-02-04 10:52:42 -080096
97 SkBitmap bm;
Matt Sarettcb6266b2017-01-17 10:48:53 -050098 bm.allocN32Pixels(kFullSize, kFullSize, false);
robertphillipsb6c65e92016-02-04 10:52:42 -080099
100 bool result = canvas->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), 0, 0);
101 SkASSERT_RELEASE(result);
102
103 // Only the center (red) portion should've been drawn into the canvas
104 REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kPad-1, kPad-1));
105 REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kPad, kPad));
106 REPORTER_ASSERT(reporter, SK_ColorRED == bm.getColor(kSmallerSize+kPad-1,
107 kSmallerSize+kPad-1));
108 REPORTER_ASSERT(reporter, SK_ColorBLUE == bm.getColor(kSmallerSize+kPad,
109 kSmallerSize+kPad));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700110
111 //--------------
Robert Phillipsa5fdc972017-02-18 16:58:09 -0500112 // Test that asImage & makeTightSurface return appropriately sized objects
robertphillipsb4bd11e2016-03-21 13:44:18 -0700113 // of the correct backing type
114 SkIRect newSubset = SkIRect::MakeWH(subset.width(), subset.height());
115 {
Robert Phillipsa5fdc972017-02-18 16:58:09 -0500116 sk_sp<SkImage> tightImg(img->asImage(&newSubset));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700117
118 REPORTER_ASSERT(reporter, tightImg->width() == subset.width());
119 REPORTER_ASSERT(reporter, tightImg->height() == subset.height());
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400120 REPORTER_ASSERT(reporter, isGPUBacked == tightImg->isTextureBacked());
robertphillipsb4bd11e2016-03-21 13:44:18 -0700121 SkPixmap tmpPixmap;
Robert Phillips6de99042017-01-31 11:31:39 -0500122 REPORTER_ASSERT(reporter, isGPUBacked != !!tightImg->peekPixels(&tmpPixmap));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700123 }
124 {
Michael Ludwig03f9ca32019-08-14 14:35:15 -0400125 sk_sp<SkSurface> tightSurf(img->makeTightSurface(kN32_SkColorType, img->getColorSpace(),
126 subset.size()));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700127
128 REPORTER_ASSERT(reporter, tightSurf->width() == subset.width());
129 REPORTER_ASSERT(reporter, tightSurf->height() == subset.height());
Robert Phillips8caf85f2018-04-05 09:30:38 -0400130 GrBackendTexture backendTex = tightSurf->getBackendTexture(
131 SkSurface::kDiscardWrite_BackendHandleAccess);
132 REPORTER_ASSERT(reporter, isGPUBacked == backendTex.isValid());
robertphillipsb4bd11e2016-03-21 13:44:18 -0700133 SkPixmap tmpPixmap;
Robert Phillips6de99042017-01-31 11:31:39 -0500134 REPORTER_ASSERT(reporter, isGPUBacked != !!tightSurf->peekPixels(&tmpPixmap));
robertphillipsb4bd11e2016-03-21 13:44:18 -0700135 }
robertphillipsb6c65e92016-02-04 10:52:42 -0800136}
137
138DEF_TEST(SpecialImage_Raster, reporter) {
139 SkBitmap bm = create_bm();
140
robertphillips37bd7c32016-03-17 14:31:39 -0700141 sk_sp<SkSpecialImage> fullSImage(SkSpecialImage::MakeFromRaster(
robertphillipsc5035e72016-03-17 06:58:39 -0700142 SkIRect::MakeWH(kFullSize, kFullSize),
Chris Daltonf5b87f92021-04-19 17:27:09 -0600143 bm, SkSurfaceProps()));
robertphillipsc5035e72016-03-17 06:58:39 -0700144
robertphillipsb6c65e92016-02-04 10:52:42 -0800145 const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
146
robertphillipsc5035e72016-03-17 06:58:39 -0700147 {
Chris Daltonf5b87f92021-04-19 17:27:09 -0600148 sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeFromRaster(subset, bm,
149 SkSurfaceProps()));
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
Mike Reeddc607e32020-12-23 11:50:36 -0500162 sk_sp<SkImage> fullImage(bm.asImage());
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),
Chris Daltonf5b87f92021-04-19 17:27:09 -0600167 fullImage,
168 SkSurfaceProps()));
robertphillipsc5035e72016-03-17 06:58:39 -0700169
robertphillipsb6c65e92016-02-04 10:52:42 -0800170 const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
171
robertphillipsc5035e72016-03-17 06:58:39 -0700172 {
Chris Daltonf5b87f92021-04-19 17:27:09 -0600173 sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeFromImage(nullptr, subset, fullImage,
174 SkSurfaceProps()));
Michael Ludwigb4580352019-06-21 16:01:42 -0400175 test_image(subSImg1, reporter, nullptr, false);
robertphillipsc5035e72016-03-17 06:58:39 -0700176 }
177
178 {
robertphillips37bd7c32016-03-17 14:31:39 -0700179 sk_sp<SkSpecialImage> subSImg2(fullSImage->makeSubset(subset));
Michael Ludwigb4580352019-06-21 16:01:42 -0400180 test_image(subSImg2, reporter, nullptr, false);
robertphillipsc5035e72016-03-17 06:58:39 -0700181 }
robertphillipsb6c65e92016-02-04 10:52:42 -0800182}
183
Brian Osman7992da32016-11-18 11:28:24 -0500184DEF_TEST(SpecialImage_Image_Legacy, reporter) {
Brian Osmanb9c49782018-10-12 12:01:22 -0400185 test_specialimage_image(reporter);
Brian Osman7992da32016-11-18 11:28:24 -0500186}
187
bsalomon68d91342016-04-12 09:59:58 -0700188DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400189 auto context = ctxInfo.directContext();
robertphillipsb6c65e92016-02-04 10:52:42 -0800190 SkBitmap bm = create_bm();
Brian Salomon27c42022021-04-28 12:39:21 -0400191 auto [view, ct] = GrMakeUncachedBitmapProxyView(context, bm);
192 if (!view) {
robertphillipsb6c65e92016-02-04 10:52:42 -0800193 return;
194 }
195
Brian Salomon27c42022021-04-28 12:39:21 -0400196 sk_sp<SkSpecialImage> fullSImg =
Brian Salomonecbb0fb2020-02-28 18:07:32 -0500197 SkSpecialImage::MakeDeferredFromGpu(context,
198 SkIRect::MakeWH(kFullSize, kFullSize),
199 kNeedNewImageUniqueID_SpecialImage,
200 view,
Brian Salomon27c42022021-04-28 12:39:21 -0400201 ct,
Chris Daltonf5b87f92021-04-19 17:27:09 -0600202 nullptr,
Brian Salomon27c42022021-04-28 12:39:21 -0400203 SkSurfaceProps());
robertphillipsc5035e72016-03-17 06:58:39 -0700204
robertphillipsb6c65e92016-02-04 10:52:42 -0800205 const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
206
robertphillipsc5035e72016-03-17 06:58:39 -0700207 {
Brian Salomon27c42022021-04-28 12:39:21 -0400208 sk_sp<SkSpecialImage> subSImg1 = SkSpecialImage::MakeDeferredFromGpu(
Brian Salomonecbb0fb2020-02-28 18:07:32 -0500209 context,
210 subset,
211 kNeedNewImageUniqueID_SpecialImage,
212 std::move(view),
Brian Salomon27c42022021-04-28 12:39:21 -0400213 ct,
Chris Daltonf5b87f92021-04-19 17:27:09 -0600214 nullptr,
Brian Salomon27c42022021-04-28 12:39:21 -0400215 SkSurfaceProps());
Michael Ludwigb4580352019-06-21 16:01:42 -0400216 test_image(subSImg1, reporter, context, true);
robertphillipsc5035e72016-03-17 06:58:39 -0700217 }
218
219 {
Brian Salomon27c42022021-04-28 12:39:21 -0400220 sk_sp<SkSpecialImage> subSImg2 = fullSImg->makeSubset(subset);
Michael Ludwigb4580352019-06-21 16:01:42 -0400221 test_image(subSImg2, reporter, context, true);
robertphillipsc5035e72016-03-17 06:58:39 -0700222 }
robertphillipsb6c65e92016-02-04 10:52:42 -0800223}