blob: 46f75cab7e6425ae7e6012c7af0776e2af7999f4 [file] [log] [blame]
Brian Salomond63638b2021-03-05 14:00:07 -05001/*
2 * Copyright 2021 Google LLC
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
Kevin Lubick8c73a592022-10-17 15:25:35 -04008#include "include/core/SkAlphaType.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkColor.h"
11#include "include/core/SkColorSpace.h"
12#include "include/core/SkColorType.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040013#include "include/core/SkImage.h"
Brian Salomond63638b2021-03-05 14:00:07 -050014#include "include/core/SkImageInfo.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040015#include "include/core/SkRect.h"
16#include "include/core/SkRefCnt.h"
Kevin Lubick0c437ea2022-10-26 07:39:24 -040017#include "include/core/SkSamplingOptions.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040018#include "include/core/SkSurface.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040019#include "include/core/SkTypes.h"
Jim Van Verthd8d33412023-03-15 14:41:28 -040020#include "include/gpu/GpuTypes.h"
Brian Salomond63638b2021-03-05 14:00:07 -050021#include "include/gpu/GrDirectContext.h"
22#include "include/gpu/GrTypes.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040023#include "include/private/SkColorData.h"
Kevin Lubick0bff57e2023-06-09 14:29:17 -040024#include "include/private/chromium/GrDeferredDisplayListRecorder.h"
25#include "include/private/chromium/GrSurfaceCharacterization.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040026#include "include/private/gpu/ganesh/GrTypesPriv.h"
Brian Salomond63638b2021-03-05 14:00:07 -050027#include "src/core/SkAutoPixmapStorage.h"
Kevin Lubickecd3a2f2023-01-05 08:17:45 -050028#include "src/gpu/SkBackingFit.h"
Kevin Lubickacdc1082023-06-09 11:05:24 -040029#include "src/gpu/ganesh/GrCanvas.h"
Greg Daniel719239c2022-04-07 11:20:24 -040030#include "src/gpu/ganesh/GrDirectContextPriv.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040031#include "src/gpu/ganesh/GrDrawingManager.h"
32#include "src/gpu/ganesh/GrImageInfo.h"
33#include "src/gpu/ganesh/GrRenderTargetProxy.h"
34#include "src/gpu/ganesh/GrRenderTask.h"
35#include "src/gpu/ganesh/GrSamplerState.h"
Greg Daniel719239c2022-04-07 11:20:24 -040036#include "src/gpu/ganesh/GrSurfaceProxy.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040037#include "src/gpu/ganesh/GrSurfaceProxyView.h"
38#include "src/gpu/ganesh/GrTextureProxy.h"
39#include "src/gpu/ganesh/SurfaceContext.h"
Greg Daniel719239c2022-04-07 11:20:24 -040040#include "src/gpu/ganesh/SurfaceFillContext.h"
Kevin Lubick8c73a592022-10-17 15:25:35 -040041#include "tests/CtsEnforcement.h"
Brian Salomond63638b2021-03-05 14:00:07 -050042#include "tests/Test.h"
43#include "tests/TestUtils.h"
44#include "tools/gpu/BackendSurfaceFactory.h"
45#include "tools/gpu/ProxyUtils.h"
46
Kevin Lubick8c73a592022-10-17 15:25:35 -040047#include <functional>
48#include <memory>
49
50struct GrContextOptions;
51
Kevin Lubickeed3b012022-09-21 11:33:19 -040052DEF_GANESH_TEST_FOR_ALL_CONTEXTS(WrappedSurfaceCopyOnWrite,
53 reporter,
54 ctxInfo,
55 CtsEnforcement::kApiLevel_T) {
Robert Phillips05039d62024-01-09 08:30:44 -050056 using namespace skgpu;
57
Brian Salomond63638b2021-03-05 14:00:07 -050058 GrDirectContext* dContext = ctxInfo.directContext();
59
Robert Phillips05039d62024-01-09 08:30:44 -050060 Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
61
Brian Salomond63638b2021-03-05 14:00:07 -050062 auto makeDirectBackendSurface = [&]() {
63 auto info = SkImageInfo::Make({10, 10}, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
64 return sk_gpu_test::MakeBackendTextureSurface(dContext,
65 info,
66 kTopLeft_GrSurfaceOrigin,
Robert Phillips05039d62024-01-09 08:30:44 -050067 /* sampleCnt= */ 1,
68 Mipmapped::kNo,
69 isProtected);
Brian Salomond63638b2021-03-05 14:00:07 -050070 };
71
72 auto imageProxyID = [&](const sk_sp<SkImage>& img) {
73 return sk_gpu_test::GetTextureImageProxy(img.get(), dContext)->uniqueID();
74 };
75
76 auto surfaceProxyID = [&](const sk_sp<SkSurface>& surf) {
Kevin Lubickacdc1082023-06-09 11:05:24 -040077 GrRenderTargetProxy* rtp = skgpu::ganesh::TopDeviceTargetProxy(surf->getCanvas());
Robert Phillipsfa8af0a2021-06-03 11:58:43 -040078 return rtp->uniqueID();
Brian Salomond63638b2021-03-05 14:00:07 -050079 };
80
81 sk_sp<SkSurface> surf = makeDirectBackendSurface();
82 surf->getCanvas()->clear(SkColor4f{1, 0, 0, 1});
83 sk_sp<SkImage> img = surf->makeImageSnapshot();
84 // Initially they share
85 REPORTER_ASSERT(reporter, surfaceProxyID(surf) == imageProxyID(img));
86 // Using the image on the direct context shouldn't affect sharing.
87 sk_sp<SkSurface> surf2 = makeDirectBackendSurface();
88 surf2->getCanvas()->drawImage(img, 0, 0);
89 REPORTER_ASSERT(reporter, surfaceProxyID(surf) == imageProxyID(img));
90 // Modifying the original surface should trigger using the copy proxy.
91 surf->getCanvas()->clear({0, 0, 1, 1});
92 REPORTER_ASSERT(reporter, surfaceProxyID(surf) != imageProxyID(img));
93 // Image caching on surface should mean another snapshot gives us the same image.
94 GrSurfaceProxy::UniqueID imageID = imageProxyID(img);
95 img = surf->makeImageSnapshot();
96 REPORTER_ASSERT(reporter, imageProxyID(img) != imageID);
97
Kevin Lubick0bff57e2023-06-09 14:29:17 -040098 GrSurfaceCharacterization characterization;
Brian Salomond63638b2021-03-05 14:00:07 -050099 REPORTER_ASSERT(reporter, surf->characterize(&characterization));
Kevin Lubick0bff57e2023-06-09 14:29:17 -0400100 GrDeferredDisplayListRecorder recorder(characterization);
Brian Salomond63638b2021-03-05 14:00:07 -0500101
102 // Using an image from a direct context on a recording context should trigger using the copy.
103 surf = makeDirectBackendSurface();
104 img = surf->makeImageSnapshot();
105 REPORTER_ASSERT(reporter, surfaceProxyID(surf) == imageProxyID(img));
106 recorder.getCanvas()->drawImage(img, 0, 0);
107 REPORTER_ASSERT(reporter, surfaceProxyID(surf) != imageProxyID(img));
108
109 // Same as above but if the surface goes out of scope first we keep using the original
110 surf = makeDirectBackendSurface();
111 img = surf->makeImageSnapshot();
112 GrSurfaceProxy::UniqueID surfID = surfaceProxyID(surf);
113 REPORTER_ASSERT(reporter, surfaceProxyID(surf) == imageProxyID(img));
114 surf.reset();
115 recorder.getCanvas()->drawImage(img, 0, 0);
116 REPORTER_ASSERT(reporter, surfID == imageProxyID(img));
117}
118
119// Make sure GrCopyRenderTasks's skip actually skips the copy.
Kevin Lubickeed3b012022-09-21 11:33:19 -0400120DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkipCopyTaskTest,
121 reporter,
122 ctxInfo,
123 CtsEnforcement::kNever) {
Brian Salomond63638b2021-03-05 14:00:07 -0500124 GrDirectContext* dContext = ctxInfo.directContext();
125
Robert Phillips1a2e7de2021-07-29 11:23:48 -0400126 GrImageInfo info(GrColorType::kRGBA_8888,
127 kPremul_SkAlphaType,
128 /*color space*/ nullptr,
129 10, 10);
Brian Salomond63638b2021-03-05 14:00:07 -0500130
Robert Phillips168296b2021-08-16 11:41:27 -0400131 auto dstSC = CreateSurfaceContext(dContext,
132 info,
133 SkBackingFit::kExact,
134 kBottomLeft_GrSurfaceOrigin,
135 GrRenderable::kYes);
Robert Phillips1a2e7de2021-07-29 11:23:48 -0400136 dstSC->asFillContext()->clear(SkPMColor4f{1, 0, 0, 1});
137
Robert Phillips168296b2021-08-16 11:41:27 -0400138 auto srcSC = CreateSurfaceContext(dContext,
139 info,
140 SkBackingFit::kExact,
141 kBottomLeft_GrSurfaceOrigin,
142 GrRenderable::kYes);
Robert Phillips1a2e7de2021-07-29 11:23:48 -0400143 srcSC->asFillContext()->clear(SkPMColor4f{0, 0, 1, 1});
Brian Salomond63638b2021-03-05 14:00:07 -0500144
145 sk_sp<GrRenderTask> task =
Michael Ludwig97838292022-09-27 10:42:01 -0400146 dContext->priv().drawingManager()->newCopyRenderTask(dstSC->asSurfaceProxyRef(),
Brian Salomond63638b2021-03-05 14:00:07 -0500147 SkIRect::MakeWH(10, 10),
Michael Ludwig97838292022-09-27 10:42:01 -0400148 srcSC->asSurfaceProxyRef(),
149 SkIRect::MakeWH(10, 10),
150 GrSamplerState::Filter::kNearest,
Brian Salomond63638b2021-03-05 14:00:07 -0500151 kTopLeft_GrSurfaceOrigin);
152
153 if (!task) {
154 ERRORF(reporter, "Couldn't make a copy task.");
155 return;
156 }
157
Adlai Hollere9ea4142021-04-27 14:31:56 -0400158 task->makeSkippable();
Brian Salomond63638b2021-03-05 14:00:07 -0500159
160 SkAutoPixmapStorage pixels;
161 pixels.alloc(SkImageInfo::Make({10, 10}, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
Robert Phillips1a2e7de2021-07-29 11:23:48 -0400162 dstSC->readPixels(dContext, pixels, {0, 0});
Brian Salomond63638b2021-03-05 14:00:07 -0500163 float kTol[4] = {};
164 std::function<ComparePixmapsErrorReporter> errorReporter(
165 [&](int x, int y, const float diffs[4]) {
166 ERRORF(reporter, "Expected {1, 0, 0, 1}. diff {%f, %f, %f, %f}",
167 diffs[0], diffs[1], diffs[2], diffs[3]);
168 });
169 CheckSolidPixels(SkColor4f{1, 0, 0, 1}, pixels, kTol, errorReporter);
170}
171
Kevin Lubick0f7b44e2023-02-28 09:13:11 -0500172#if defined(SK_GANESH)
Robert Phillips1a2e7de2021-07-29 11:23:48 -0400173
Robert Phillips3e87a8e2021-08-25 13:22:24 -0400174// Make sure OpsTask are skippable
Kevin Lubickeed3b012022-09-21 11:33:19 -0400175DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkipOpsTaskTest, reporter, ctxInfo, CtsEnforcement::kNever) {
Brian Salomond63638b2021-03-05 14:00:07 -0500176 GrDirectContext* dContext = ctxInfo.directContext();
177
Robert Phillips643f4812021-08-11 09:31:00 -0400178 GrImageInfo ii(GrColorType::kRGBA_8888, kPremul_SkAlphaType, /*color space*/ nullptr, 10, 10);
179
Aditya Kushwah97f17482022-08-31 17:04:26 -0700180 auto dst = dContext->priv().makeSFC(ii, /*label=*/{}, SkBackingFit::kExact);
Brian Salomond63638b2021-03-05 14:00:07 -0500181 dst->clear(SkPMColor4f{1, 0, 0, 1});
182 dContext->flush();
183
184 dst->clear(SkPMColor4f{0, 0, 1, 1});
Robert Phillips643f4812021-08-11 09:31:00 -0400185 sk_sp<GrRenderTask> task = dst->refRenderTask();
Brian Salomond63638b2021-03-05 14:00:07 -0500186
187 // GrDrawingManager maintains an "active ops task" and doesn't like having it closed behind
188 // its back. temp exists just to replace dst's ops task as the active one.
Aditya Kushwah97f17482022-08-31 17:04:26 -0700189 auto temp = dContext->priv().makeSFC(ii, /*label=*/{}, SkBackingFit::kExact);
Brian Salomond63638b2021-03-05 14:00:07 -0500190 temp->clear(SkPMColor4f{0, 0, 0, 0});
191
192 GrSurfaceProxyView readView = dst->readSurfaceView();
Adlai Hollere9ea4142021-04-27 14:31:56 -0400193 task->makeSkippable();
Brian Salomond63638b2021-03-05 14:00:07 -0500194
195 SkAutoPixmapStorage pixels;
196 pixels.alloc(SkImageInfo::Make({10, 10}, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
197 dst->readPixels(dContext, pixels, {0, 0});
198 float kTol[4] = {};
199 std::function<ComparePixmapsErrorReporter> errorReporter(
200 [&](int x, int y, const float diffs[4]) {
201 ERRORF(reporter, "Expected {1, 0, 0, 1}. diff {%f, %f, %f, %f}",
202 diffs[0], diffs[1], diffs[2], diffs[3]);
203 });
204 CheckSolidPixels(SkColor4f{1, 0, 0, 1}, pixels, kTol, errorReporter);
205}
Kevin Lubick0f7b44e2023-02-28 09:13:11 -0500206#endif // defined(SK_GANESH)