1 /*
2 * Copyright 2014 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
8 #include "include/core/SkBitmap.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkImage.h"
12 #include "include/core/SkImageInfo.h"
13 #include "include/core/SkMatrix.h"
14 #include "include/core/SkPaint.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/core/SkSamplingOptions.h"
18 #include "include/core/SkScalar.h"
19 #include "include/core/SkShader.h"
20 #include "include/core/SkSurface.h"
21 #include "include/core/SkTileMode.h"
22 #include "include/core/SkTypes.h"
23 #include "include/gpu/GpuTypes.h"
24 #include "include/gpu/ganesh/GrDirectContext.h"
25 #include "include/gpu/ganesh/SkSurfaceGanesh.h"
26 #include "tests/CtsEnforcement.h"
27 #include "tests/Test.h"
28 #include "tools/DecodeUtils.h"
29 #include "tools/Resources.h"
30
31 #include <cstring>
32
33 class GrRecordingContext;
34 struct GrContextOptions;
35
test_bitmap_equality(skiatest::Reporter * reporter,SkBitmap & bm1,SkBitmap & bm2)36 static void test_bitmap_equality(skiatest::Reporter* reporter, SkBitmap& bm1, SkBitmap& bm2) {
37 REPORTER_ASSERT(reporter, bm1.computeByteSize() == bm2.computeByteSize());
38 REPORTER_ASSERT(reporter, 0 == memcmp(bm1.getPixels(), bm2.getPixels(), bm1.computeByteSize()));
39 }
40
paint_source(SkSurface * sourceSurface)41 static void paint_source(SkSurface* sourceSurface) {
42 SkCanvas* sourceCanvas = sourceSurface->getCanvas();
43 sourceCanvas->clear(0xFFDEDEDE);
44
45 SkPaint paintColor;
46 paintColor.setColor(0xFFFF0000);
47 paintColor.setStyle(SkPaint::kFill_Style);
48
49 SkRect rect = SkRect::MakeXYWH(
50 SkIntToScalar(1),
51 SkIntToScalar(0),
52 SkIntToScalar(1),
53 SkIntToScalar(sourceSurface->height()));
54
55 sourceCanvas->drawRect(rect, paintColor);
56 }
57
run_shader_test(skiatest::Reporter * reporter,SkSurface * sourceSurface,SkSurface * destinationSurface,SkImageInfo & info)58 static void run_shader_test(skiatest::Reporter* reporter, SkSurface* sourceSurface,
59 SkSurface* destinationSurface, SkImageInfo& info) {
60 paint_source(sourceSurface);
61
62 sk_sp<SkImage> sourceImage(sourceSurface->makeImageSnapshot());
63 sk_sp<SkShader> sourceShader = sourceImage->makeShader(
64 SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions());
65
66 SkPaint paint;
67 paint.setShader(sourceShader);
68
69 SkCanvas* destinationCanvas = destinationSurface->getCanvas();
70 destinationCanvas->clear(SK_ColorTRANSPARENT);
71 destinationCanvas->drawPaint(paint);
72
73 SkBitmap bmOrig;
74 bmOrig.allocN32Pixels(info.width(), info.height());
75 sourceSurface->readPixels(bmOrig, 0, 0);
76
77
78 SkBitmap bm;
79 bm.allocN32Pixels(info.width(), info.height());
80 destinationSurface->readPixels(bm, 0, 0);
81
82 test_bitmap_equality(reporter, bmOrig, bm);
83
84 // Test with a translated shader
85 SkMatrix matrix;
86 matrix.setTranslate(SkIntToScalar(-1), SkIntToScalar(0));
87
88 sk_sp<SkShader> sourceShaderTranslated = sourceImage->makeShader(
89 SkTileMode::kRepeat,
90 SkTileMode::kRepeat,
91 SkSamplingOptions(), &matrix);
92
93 destinationCanvas->clear(SK_ColorTRANSPARENT);
94
95 SkPaint paintTranslated;
96 paintTranslated.setShader(sourceShaderTranslated);
97
98 destinationCanvas->drawPaint(paintTranslated);
99
100 SkBitmap bmt;
101 bmt.allocN32Pixels(info.width(), info.height());
102 destinationSurface->readPixels(bmt, 0, 0);
103
104 // Test correctness
105 {
106 for (int y = 0; y < info.height(); y++) {
107 REPORTER_ASSERT(reporter, 0xFFFF0000 == bmt.getColor(0, y));
108
109 for (int x = 1; x < info.width(); x++) {
110 REPORTER_ASSERT(reporter, 0xFFDEDEDE == bmt.getColor(x, y));
111 }
112 }
113 }
114 }
115
DEF_TEST(ImageNewShader,reporter)116 DEF_TEST(ImageNewShader, reporter) {
117 SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
118
119 auto sourceSurface(SkSurfaces::Raster(info));
120 auto destinationSurface(SkSurfaces::Raster(info));
121
122 run_shader_test(reporter, sourceSurface.get(), destinationSurface.get(), info);
123 }
124
gpu_to_gpu(skiatest::Reporter * reporter,GrRecordingContext * rContext)125 static void gpu_to_gpu(skiatest::Reporter* reporter, GrRecordingContext* rContext) {
126 SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
127
128 auto sourceSurface(SkSurfaces::RenderTarget(rContext, skgpu::Budgeted::kNo, info));
129 auto destinationSurface(SkSurfaces::RenderTarget(rContext, skgpu::Budgeted::kNo, info));
130
131 run_shader_test(reporter, sourceSurface.get(), destinationSurface.get(), info);
132 }
133
raster_to_gpu(skiatest::Reporter * reporter,GrRecordingContext * rContext)134 static void raster_to_gpu(skiatest::Reporter* reporter, GrRecordingContext* rContext) {
135 SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
136
137 auto sourceSurface(SkSurfaces::Raster(info));
138 auto destinationSurface(SkSurfaces::RenderTarget(rContext, skgpu::Budgeted::kNo, info));
139
140 run_shader_test(reporter, sourceSurface.get(), destinationSurface.get(), info);
141 }
142
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(ImageNewShader_GPU,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)143 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(ImageNewShader_GPU,
144 reporter,
145 ctxInfo,
146 CtsEnforcement::kApiLevel_T) {
147 auto dContext = ctxInfo.directContext();
148
149 // GPU -> GPU
150 gpu_to_gpu(reporter, dContext);
151
152 // GPU -> RASTER not currently supported
153
154 // RASTER -> GPU
155 raster_to_gpu(reporter, dContext);
156 }
157
DEF_TEST(ImageRawShader,reporter)158 DEF_TEST(ImageRawShader, reporter) {
159 auto image = ToolUtils::GetResourceAsImage("images/mandrill_32.png");
160 REPORTER_ASSERT(reporter, image);
161
162 // We should be able to turn this into a "raw" image shader:
163 REPORTER_ASSERT(reporter, image->makeRawShader(SkFilterMode::kNearest));
164
165 // ... but not if we request cubic filtering
166 REPORTER_ASSERT(reporter, !image->makeRawShader(SkCubicResampler::Mitchell()));
167 }
168