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/SkFont.h"
12 #include "include/gpu/graphite/Context.h"
13 #include "include/gpu/graphite/Recording.h"
14 #include "include/gpu/graphite/Surface.h"
15 #include "src/gpu/graphite/ContextPriv.h"
16 #include "src/gpu/graphite/Surface_Graphite.h"
17 #include "tests/TestUtils.h"
18 #include "tools/ToolUtils.h"
19 #include "tools/fonts/FontToolUtils.h"
20
21 using namespace skgpu::graphite;
22
23 namespace {
24
25 const SkISize kSurfaceSize = { 64, 64 };
26
27 constexpr SkColor4f kBackgroundColor = SkColors::kWhite;
28
run_test(skiatest::Reporter * reporter,Context * context,Recorder * recorder)29 bool run_test(skiatest::Reporter* reporter,
30 Context* context,
31 Recorder* recorder) {
32 SkImageInfo ii = SkImageInfo::Make(kSurfaceSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
33
34 SkBitmap result0, result1;
35 result0.allocPixels(ii);
36 result1.allocPixels(ii);
37 SkPixmap pm0, pm1;
38
39 SkAssertResult(result0.peekPixels(&pm0));
40 SkAssertResult(result1.peekPixels(&pm1));
41
42 sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder, ii);
43 if (!surface) {
44 ERRORF(reporter, "Surface creation failed");
45 return false;
46 }
47
48 SkCanvas* canvas = surface->getCanvas();
49
50 // Set up a recording to clear the surface
51 canvas->clear(kBackgroundColor);
52 std::unique_ptr<Recording> clearRecording = recorder->snap();
53 if (!clearRecording) {
54 ERRORF(reporter, "Recording creation failed");
55 return false;
56 }
57
58 // Draw some text and get recording
59 SkPaint paint;
60 paint.setAntiAlias(true);
61
62 SkFont font(ToolUtils::CreatePortableTypeface("serif", SkFontStyle()));
63 font.setSubpixel(true);
64 font.setSize(12);
65
66 const char* text0 = "Hamburge";
67 const size_t text0Len = strlen(text0);
68
69 canvas->drawSimpleText(text0, text0Len, SkTextEncoding::kUTF8, 3, 20, font, paint);
70 std::unique_ptr<Recording> text0Recording = recorder->snap();
71
72 // Draw some more text and get recording
73 const char* text1 = "burgefons";
74 const size_t text1Len = strlen(text1);
75
76 canvas->drawSimpleText(text1, text1Len, SkTextEncoding::kUTF8, 3, 40, font, paint);
77 std::unique_ptr<Recording> text1Recording = recorder->snap();
78
79 // Playback 0, then 1, and read pixels
80 InsertRecordingInfo info;
81 info.fRecording = clearRecording.get();
82 context->insertRecording(info);
83 info.fRecording = text0Recording.get();
84 context->insertRecording(info);
85 info.fRecording = text1Recording.get();
86 context->insertRecording(info);
87 context->submit();
88
89 if (!surface->readPixels(pm0, 0, 0)) {
90 ERRORF(reporter, "readPixels failed");
91 return false;
92 }
93
94 // Playback 1, then 0, and read pixels
95 info.fRecording = clearRecording.get();
96 context->insertRecording(info);
97 info.fRecording = text1Recording.get();
98 context->insertRecording(info);
99 info.fRecording = text0Recording.get();
100 context->insertRecording(info);
101 context->submit();
102
103 if (!surface->readPixels(pm1, 0, 0)) {
104 ERRORF(reporter, "readPixels failed");
105 return false;
106 }
107
108 // Compare and contrast
109 float tol = 1.f/256;
110 const float tols[4] = {tol, tol, tol, tol};
111 auto error = std::function<ComparePixmapsErrorReporter>([&](int x, int y,
112 const float diffs[4]) {
113 SkASSERT(x >= 0 && y >= 0);
114 ERRORF(reporter,
115 "Error at %d, %d. Diff in floats: (%f, %f, %f, %f)",
116 x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
117 });
118 ComparePixels(pm0, pm1, tols, error);
119
120 return true;
121 }
122
123 } // anonymous namespace
124
125 // This test captures two recordings A and B, plays them back as A then B, and B then A,
126 // and verifies that the result is the same.
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(RecordingOrderTest_Graphite,reporter,context,CtsEnforcement::kApiLevel_V)127 DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(RecordingOrderTest_Graphite, reporter, context,
128 CtsEnforcement::kApiLevel_V) {
129 std::unique_ptr<Recorder> recorder = context->makeRecorder();
130
131 (void) run_test(reporter, context, recorder.get());
132 }
133