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 "SkCanvas.h"
9 #include "SkImage.h"
10 #include "SkShader.h"
11 #include "SkSurface.h"
12 #include "SkTypes.h"
13 #include "Test.h"
14 
15 #if SK_SUPPORT_GPU
16 #include "GrContext.h"
17 #endif
18 
testBitmapEquality(skiatest::Reporter * reporter,SkBitmap & bm1,SkBitmap & bm2)19 void testBitmapEquality(skiatest::Reporter* reporter, SkBitmap& bm1, SkBitmap& bm2) {
20     SkAutoLockPixels lockBm1(bm1);
21     SkAutoLockPixels lockBm2(bm2);
22 
23     REPORTER_ASSERT(reporter, bm1.getSize() == bm2.getSize());
24     REPORTER_ASSERT(reporter, 0 == memcmp(bm1.getPixels(), bm2.getPixels(), bm1.getSize()));
25 }
26 
paintSource(SkSurface * sourceSurface)27 void paintSource(SkSurface* sourceSurface) {
28     SkCanvas* sourceCanvas = sourceSurface->getCanvas();
29     sourceCanvas->clear(0xFFDEDEDE);
30 
31     SkPaint paintColor;
32     paintColor.setColor(0xFFFF0000);
33     paintColor.setStyle(SkPaint::kFill_Style);
34 
35     SkRect rect = SkRect::MakeXYWH(
36             SkIntToScalar(1),
37             SkIntToScalar(0),
38             SkIntToScalar(1),
39             SkIntToScalar(sourceSurface->height()));
40 
41     sourceCanvas->drawRect(rect, paintColor);
42 }
43 
runShaderTest(skiatest::Reporter * reporter,SkSurface * sourceSurface,SkSurface * destinationSurface,SkImageInfo & info)44 void runShaderTest(skiatest::Reporter* reporter, SkSurface* sourceSurface, SkSurface* destinationSurface, SkImageInfo& info) {
45     paintSource(sourceSurface);
46 
47     SkAutoTUnref<SkImage> sourceImage(sourceSurface->newImageSnapshot());
48     SkAutoTUnref<SkShader> sourceShader(sourceImage->newShader(
49             SkShader::kRepeat_TileMode,
50             SkShader::kRepeat_TileMode));
51 
52     SkPaint paint;
53     paint.setShader(sourceShader);
54 
55     SkCanvas* destinationCanvas = destinationSurface->getCanvas();
56     destinationCanvas->clear(SK_ColorTRANSPARENT);
57     destinationCanvas->drawPaint(paint);
58 
59     SkIRect rect = info.bounds();
60 
61     SkBitmap bmOrig;
62     sourceSurface->getCanvas()->readPixels(rect, &bmOrig);
63 
64 
65     SkBitmap bm;
66     destinationCanvas->readPixels(rect, &bm);
67 
68     testBitmapEquality(reporter, bmOrig, bm);
69 
70 
71 
72     // Test with a translated shader
73     SkMatrix matrix;
74     matrix.setTranslate(SkIntToScalar(-1), SkIntToScalar(0));
75 
76     SkAutoTUnref<SkShader> sourceShaderTranslated(sourceImage->newShader(
77             SkShader::kRepeat_TileMode,
78             SkShader::kRepeat_TileMode,
79             &matrix));
80 
81     destinationCanvas->clear(SK_ColorTRANSPARENT);
82 
83     SkPaint paintTranslated;
84     paintTranslated.setShader(sourceShaderTranslated);
85 
86     destinationCanvas->drawPaint(paintTranslated);
87 
88     SkBitmap bmt;
89     destinationCanvas->readPixels(rect, &bmt);
90 
91     //  Test correctness
92     {
93         SkAutoLockPixels lockBm(bmt);
94         for (int y = 0; y < info.height(); y++) {
95             REPORTER_ASSERT(reporter, 0xFFFF0000 == bmt.getColor(0, y));
96 
97             for (int x = 1; x < info.width(); x++) {
98                 REPORTER_ASSERT(reporter, 0xFFDEDEDE == bmt.getColor(x, y));
99             }
100         }
101     }
102 }
103 
DEF_TEST(ImageNewShader,reporter)104 DEF_TEST(ImageNewShader, reporter) {
105     SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
106 
107     SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRaster(info));
108     SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRaster(info));
109 
110     runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
111 }
112 
113 #if SK_SUPPORT_GPU
114 
gpuToGpu(skiatest::Reporter * reporter,GrContext * context)115 void gpuToGpu(skiatest::Reporter* reporter, GrContext* context) {
116     SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
117 
118     SkAutoTUnref<SkSurface> sourceSurface(
119         SkSurface::NewRenderTarget(context, SkBudgeted::kNo, info));
120     SkAutoTUnref<SkSurface> destinationSurface(
121         SkSurface::NewRenderTarget(context, SkBudgeted::kNo, info));
122 
123     runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
124 }
125 
gpuToRaster(skiatest::Reporter * reporter,GrContext * context)126 void gpuToRaster(skiatest::Reporter* reporter, GrContext* context) {
127     SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
128 
129     SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRenderTarget(context,
130         SkBudgeted::kNo, info));
131     SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRaster(info));
132 
133     runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
134 }
135 
rasterToGpu(skiatest::Reporter * reporter,GrContext * context)136 void rasterToGpu(skiatest::Reporter* reporter, GrContext* context) {
137     SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
138 
139     SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRaster(info));
140     SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRenderTarget(context,
141         SkBudgeted::kNo, info));
142 
143     runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
144 }
145 
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageNewShader_GPU,reporter,context)146 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageNewShader_GPU, reporter, context) {
147     //  GPU -> GPU
148     gpuToGpu(reporter, context);
149 
150     //  GPU -> RASTER
151     gpuToRaster(reporter, context);
152 
153     //  RASTER -> GPU
154     rasterToGpu(reporter, context);
155 }
156 
157 #endif
158