• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 
8 #include "tests/Test.h"
9 
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkPixmap.h"
13 #include "include/gpu/graphite/Context.h"
14 #include "include/gpu/graphite/Recorder.h"
15 #include "include/gpu/graphite/Recording.h"
16 #include "include/gpu/graphite/Surface.h"
17 #include "src/gpu/graphite/RecordingPriv.h"
18 #include "src/gpu/graphite/Surface_Graphite.h"
19 
20 namespace skgpu::graphite {
21 
22 using DrawCallback = std::function<void(SkCanvas*)>;
23 
24 struct Expectation {
25     int fX;
26     int fY;
27     SkColor4f fColor;
28 };
29 
run_test(skiatest::Reporter * reporter,Context * context,SkISize surfaceSize,SkISize recordingSize,SkISize replayOffset,DrawCallback draw,const std::vector<Expectation> & expectations)30 void run_test(skiatest::Reporter* reporter,
31               Context* context,
32               SkISize surfaceSize,
33               SkISize recordingSize,
34               SkISize replayOffset,
35               DrawCallback draw,
36               const std::vector<Expectation>& expectations) {
37     const SkImageInfo surfaceImageInfo = SkImageInfo::Make(
38             surfaceSize, SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kPremul_SkAlphaType);
39 
40     std::unique_ptr<Recorder> surfaceRecorder = context->makeRecorder();
41     sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(surfaceRecorder.get(), surfaceImageInfo);
42     Surface* graphiteSurface = static_cast<Surface*>(surface.get());
43     const TextureInfo& textureInfo = graphiteSurface->backingTextureProxy()->textureInfo();
44 
45     // Flush the initial clear added by MakeGraphite.
46     std::unique_ptr<skgpu::graphite::Recording> surfaceRecording = surfaceRecorder->snap();
47     context->insertRecording({surfaceRecording.get()});
48 
49     // Snap a recording without a bound target.
50     const SkImageInfo recordingImageInfo = surfaceImageInfo.makeDimensions(recordingSize);
51     std::unique_ptr<Recorder> recorder = context->makeRecorder();
52     SkCanvas* canvas = recorder->makeDeferredCanvas(recordingImageInfo, textureInfo);
53     draw(canvas);
54 
55     // Can't make another canvas before snapping.
56     REPORTER_ASSERT(reporter,
57                     recorder->makeDeferredCanvas(recordingImageInfo, textureInfo) == nullptr);
58     std::unique_ptr<Recording> recording = recorder->snap();
59 
60     // Play back recording.
61     context->insertRecording(
62             {recording.get(), surface.get(), {replayOffset.fWidth, replayOffset.fHeight}});
63 
64     // Read pixels.
65     SkBitmap bitmap;
66     SkPixmap pixmap;
67     bitmap.allocPixels(surfaceImageInfo);
68     SkAssertResult(bitmap.peekPixels(&pixmap));
69     if (!surface->readPixels(pixmap, 0, 0)) {
70         ERRORF(reporter, "readPixels failed");
71         return;
72     }
73 
74     // Veryify expectations are met and recording is uninstantiated.
75     REPORTER_ASSERT(reporter, !recording->priv().isTargetProxyInstantiated());
76     for (const Expectation& e : expectations) {
77         SkColor4f color = pixmap.getColor4f(e.fX, e.fY);
78 #ifdef SK_DEBUG
79         if (color != e.fColor) {
80             SkDebugf("Wrong color\n\texpected: %f %f %f %f\n\tactual: %f %f %f %f",
81                      e.fColor.fR,
82                      e.fColor.fG,
83                      e.fColor.fB,
84                      e.fColor.fA,
85                      color.fR,
86                      color.fG,
87                      color.fB,
88                      color.fA);
89         }
90 #endif
91         REPORTER_ASSERT(reporter, color == e.fColor);
92     }
93 }
94 
95 // Tests that clear does not clear an entire replayed-to surface if recorded onto a smaller surface.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestClear,reporter,context,CtsEnforcement::kNextRelease)96 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestClear, reporter, context,
97                                    CtsEnforcement::kNextRelease) {
98     SkISize surfaceSize = SkISize::Make(8, 4);
99     SkISize recordingSize = SkISize::Make(4, 4);
100     SkISize replayOffset = SkISize::Make(0, 0);
101 
102     auto draw = [](SkCanvas* canvas) { canvas->clear(SkColors::kRed); };
103 
104     std::vector<Expectation> expectations = {{0, 0, SkColors::kRed},
105                                              {4, 0, SkColors::kTransparent}};
106 
107     run_test(reporter, context, surfaceSize, recordingSize, replayOffset, draw, expectations);
108 }
109 
110 // Tests that writePixels is translated correctly when replayed with an offset.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestWritePixels,reporter,context,CtsEnforcement::kNextRelease)111 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestWritePixels, reporter, context,
112                                    CtsEnforcement::kNextRelease) {
113     SkBitmap bitmap;
114     bitmap.allocN32Pixels(4, 4, true);
115     SkCanvas bitmapCanvas(bitmap);
116     SkPaint paint;
117     paint.setColor(SkColors::kRed);
118     bitmapCanvas.drawIRect(SkIRect::MakeXYWH(0, 0, 4, 4), paint);
119 
120     SkISize surfaceSize = SkISize::Make(8, 4);
121     SkISize recordingSize = SkISize::Make(4, 4);
122     SkISize replayOffset = SkISize::Make(4, 0);
123 
124     auto draw = [&bitmap](SkCanvas* canvas) { canvas->writePixels(bitmap, 0, 0); };
125 
126     std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent},
127                                              {4, 0, SkColors::kRed}};
128 
129     run_test(reporter, context, surfaceSize, recordingSize, replayOffset, draw, expectations);
130 }
131 
132 // Tests that the result of writePixels is cropped correctly when offscreen.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestWritePixelsOffscreen,reporter,context,CtsEnforcement::kNextRelease)133 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestWritePixelsOffscreen, reporter, context,
134                                    CtsEnforcement::kNextRelease) {
135     SkBitmap bitmap;
136     bitmap.allocN32Pixels(4, 4, true);
137     SkCanvas bitmapCanvas(bitmap);
138     SkPaint paint;
139     paint.setColor(SkColors::kRed);
140     bitmapCanvas.drawIRect(SkIRect::MakeXYWH(0, 0, 4, 4), paint);
141     paint.setColor(SkColors::kGreen);
142     bitmapCanvas.drawIRect(SkIRect::MakeXYWH(2, 2, 2, 2), paint);
143 
144     SkISize surfaceSize = SkISize::Make(4, 4);
145     SkISize recordingSize = SkISize::Make(4, 4);
146     SkISize replayOffset = SkISize::Make(-2, -2);
147 
148     auto draw = [&bitmap](SkCanvas* canvas) { canvas->writePixels(bitmap, 0, 0); };
149 
150     std::vector<Expectation> expectations = {{0, 0, SkColors::kGreen}};
151 
152     run_test(reporter, context, surfaceSize, recordingSize, replayOffset, draw, expectations);
153 }
154 
155 }  // namespace skgpu::graphite
156