@@ -51,29 +51,49 @@ class RectangleTexture : public GpuGM {
5151 this ->setBGColor (0xFFFFFFFF );
5252 }
5353
54- protected:
54+ private:
55+ enum class ImageType {
56+ kGradientCircle ,
57+ k2x2
58+ };
59+
5560 SkString onShortName () override {
5661 return SkString (" rectangle_texture" );
5762 }
5863
59- SkISize onISize () override { return SkISize::Make (1200 , 500 ); }
60-
61- void fillPixels (int width, int height, void *pixels) {
62- SkBitmap bmp;
63- bmp.setInfo (SkImageInfo::Make (width, height, kRGBA_8888_SkColorType , kOpaque_SkAlphaType ));
64- bmp.setPixels (pixels);
65- SkPaint paint;
66- SkCanvas canvas (bmp);
67- SkPoint pts[] = { {0 , 0 }, {0 , SkIntToScalar (height)} };
68- SkColor colors0[] = { 0xFF1060B0 , 0xFF102030 };
69- paint.setShader (SkGradientShader::MakeLinear (pts, colors0, nullptr , 2 , SkTileMode::kClamp ));
70- canvas.drawPaint (paint);
71-
72- SkColor colors1[] = {0xFFA07010 , 0xFFA02080 };
73- paint.setAntiAlias (true );
74- paint.setShader (SkGradientShader::MakeLinear (pts, colors1, nullptr , 2 , SkTileMode::kClamp ));
75- canvas.drawCircle (SkIntToScalar (width) / 2 , SkIntToScalar (height) / 2 ,
76- SkIntToScalar (width + height) / 5 , paint);
64+ SkISize onISize () override { return SkISize::Make (1180 , 710 ); }
65+
66+ SkBitmap makeImagePixels (int size, ImageType type) {
67+ auto ii = SkImageInfo::Make (size, size, kRGBA_8888_SkColorType , kOpaque_SkAlphaType );
68+ switch (type) {
69+ case ImageType::kGradientCircle : {
70+ SkBitmap bmp;
71+ bmp.allocPixels (ii);
72+ SkPaint paint;
73+ SkCanvas canvas (bmp);
74+ SkPoint pts[] = {{0 , 0 }, {0 , SkIntToScalar (size)}};
75+ SkColor colors0[] = {0xFF1060B0 , 0xFF102030 };
76+ paint.setShader (
77+ SkGradientShader::MakeLinear (pts, colors0, nullptr , 2 , SkTileMode::kClamp ));
78+ canvas.drawPaint (paint);
79+ SkColor colors1[] = {0xFFA07010 , 0xFFA02080 };
80+ paint.setAntiAlias (true );
81+ paint.setShader (
82+ SkGradientShader::MakeLinear (pts, colors1, nullptr , 2 , SkTileMode::kClamp ));
83+ canvas.drawCircle (size/2 .f , size/2 .f , 2 .f *size/5 , paint);
84+ return bmp;
85+ }
86+ case ImageType::k2x2: {
87+ SkBitmap bmp;
88+ bmp.allocPixels (ii);
89+ *bmp.getAddr32 (0 , 0 ) = 0xFF0000FF ;
90+ *bmp.getAddr32 (1 , 0 ) = 0xFF00FF00 ;
91+ *bmp.getAddr32 (0 , 1 ) = 0xFFFF0000 ;
92+ *bmp.getAddr32 (1 , 1 ) = 0xFFFFFFFF ;
93+ return bmp;
94+ }
95+ }
96+ SkUNREACHABLE;
7797 }
7898
7999 static const GrGLContext* GetGLContextIfSupported (GrContext* context) {
@@ -87,8 +107,10 @@ class RectangleTexture : public GpuGM {
87107 return context->priv ().getGpu ()->glContextForTesting ();
88108 }
89109
90- sk_sp<SkImage> createRectangleTextureImg (GrContext* context, GrSurfaceOrigin origin, int width,
91- int height, const uint32_t * pixels) {
110+ sk_sp<SkImage> createRectangleTextureImg (GrContext* context, GrSurfaceOrigin origin,
111+ const SkBitmap content) {
112+ SkASSERT (content.colorType () == kRGBA_8888_SkColorType );
113+
92114 const GrGLContext* glCtx = GetGLContextIfSupported (context);
93115 if (!glCtx) {
94116 return nullptr ;
@@ -106,26 +128,29 @@ class RectangleTexture : public GpuGM {
106128 GR_GL_CALL (gl, TexParameteri (kTarget , GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
107129 GR_GL_CALL (gl, TexParameteri (kTarget , GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
108130 std::unique_ptr<uint32_t []> tempPixels;
131+ auto src = content.getAddr32 (0 , 0 );
132+ int h = content.height ();
133+ int w = content.width ();
109134 if (origin == kBottomLeft_GrSurfaceOrigin ) {
110- tempPixels.reset (new uint32_t [width * height ]);
111- for (int y = 0 ; y < height ; ++y) {
112- std::copy_n (pixels + width * (height - y - 1 ), width , tempPixels.get () + width * y);
135+ tempPixels.reset (new uint32_t [w * h ]);
136+ for (int y = 0 ; y < h ; ++y) {
137+ std::copy_n (src + w*(h - y - 1 ), w , tempPixels.get () + w* y);
113138 }
114- pixels = tempPixels.get ();
139+ src = tempPixels.get ();
115140 }
116- GR_GL_CALL (gl, TexImage2D (kTarget , 0 , GR_GL_RGBA, width, height , 0 , GR_GL_RGBA,
117- GR_GL_UNSIGNED_BYTE, pixels ));
141+ GR_GL_CALL (gl, TexImage2D (kTarget , 0 , GR_GL_RGBA, w, h , 0 , GR_GL_RGBA, GR_GL_UNSIGNED_BYTE ,
142+ src ));
118143
119144 context->resetContext ();
120145 GrGLTextureInfo info;
121146 info.fID = id;
122147 info.fTarget = kTarget ;
123148 info.fFormat = GR_GL_RGBA8;
124149
125- GrBackendTexture rectangleTex (width, height , GrMipMapped::kNo , info);
150+ GrBackendTexture rectangleTex (w, h , GrMipMapped::kNo , info);
126151
127- if (sk_sp<SkImage> image = SkImage::MakeFromAdoptedTexture (context, rectangleTex, origin,
128- kRGBA_8888_SkColorType )) {
152+ if (sk_sp<SkImage> image = SkImage::MakeFromAdoptedTexture (
153+ context, rectangleTex, origin, content. colorType (), content. alphaType () )) {
129154 return image;
130155 }
131156 GR_GL_CALL (gl, DeleteTextures (1 , &id));
@@ -135,25 +160,19 @@ class RectangleTexture : public GpuGM {
135160 DrawResult onDraw (GrContext* context, GrRenderTargetContext*, SkCanvas* canvas,
136161 SkString* errorMsg) override {
137162 if (!GetGLContextIfSupported (context)) {
138- *errorMsg = " this GM requires an OpenGL 3.1+ context" ;
163+ *errorMsg = " This GM requires an OpenGL context that supports texture rectangles. " ;
139164 return DrawResult::kSkip ;
140165 }
141166
142- constexpr int kWidth = 50 ;
143- constexpr int kHeight = 50 ;
144- constexpr SkScalar kPad = 5 .f ;
167+ auto gradCircle = this ->makeImagePixels (50 , ImageType::kGradientCircle );
168+ static constexpr SkScalar kPad = 5 .f ;
145169
146- SkPMColor pixels[kWidth * kHeight ];
147- this ->fillPixels (kWidth , kHeight , pixels);
148-
149- sk_sp<SkImage> rectImgs[] = {
150- this ->createRectangleTextureImg (context, kTopLeft_GrSurfaceOrigin , kWidth , kHeight ,
151- pixels),
152- this ->createRectangleTextureImg (context, kBottomLeft_GrSurfaceOrigin , kWidth ,
153- kHeight , pixels),
170+ sk_sp<SkImage> gradImgs[] = {
171+ this ->createRectangleTextureImg (context, kTopLeft_GrSurfaceOrigin , gradCircle),
172+ this ->createRectangleTextureImg (context, kBottomLeft_GrSurfaceOrigin , gradCircle),
154173 };
155- SkASSERT (SkToBool (rectImgs [0 ]) == SkToBool (rectImgs [1 ]));
156- if (!rectImgs [0 ]) {
174+ SkASSERT (SkToBool (gradImgs [0 ]) == SkToBool (gradImgs [1 ]));
175+ if (!gradImgs [0 ]) {
157176 *errorMsg = " Could not create rectangle texture image." ;
158177 return DrawResult::kFail ;
159178 }
@@ -168,48 +187,80 @@ class RectangleTexture : public GpuGM {
168187 constexpr SkScalar kScales [] = {1 .0f , 1 .2f , 0 .75f };
169188
170189 canvas->translate (kPad , kPad );
171- for (size_t i = 0 ; i < SK_ARRAY_COUNT (rectImgs); ++i) {
190+ for (size_t i = 0 ; i < SK_ARRAY_COUNT (gradImgs); ++i) {
191+ auto img = gradImgs[i];
192+ int w = img->width ();
193+ int h = img->height ();
172194 for (auto s : kScales ) {
173195 canvas->save ();
174196 canvas->scale (s, s);
175197 for (auto q : kQualities ) {
176198 // drawImage
177199 SkPaint plainPaint;
178200 plainPaint.setFilterQuality (q);
179- canvas->drawImage (rectImgs[i] , 0 , 0 , &plainPaint);
180- canvas->translate (kWidth + kPad , 0 );
201+ canvas->drawImage (img , 0 , 0 , &plainPaint);
202+ canvas->translate (w + kPad , 0 );
181203
182204 // clamp/clamp shader
183205 SkPaint clampPaint;
184206 clampPaint.setFilterQuality (q);
185- clampPaint.setShader (rectImgs [i]->makeShader ());
186- canvas->drawRect (SkRect::MakeWH (1 .5f * kWidth , 1 .5f * kHeight ), clampPaint);
187- canvas->translate (kWidth * 1 .5f + kPad , 0 );
207+ clampPaint.setShader (gradImgs [i]->makeShader ());
208+ canvas->drawRect (SkRect::MakeWH (1 .5f *w , 1 .5f *h ), clampPaint);
209+ canvas->translate (1 .5f *w + kPad , 0 );
188210
189211 // repeat/mirror shader
190212 SkPaint repeatPaint;
191213 repeatPaint.setFilterQuality (q);
192- repeatPaint.setShader (rectImgs [i]->makeShader (SkTileMode::kRepeat ,
214+ repeatPaint.setShader (gradImgs [i]->makeShader (SkTileMode::kRepeat ,
193215 SkTileMode::kMirror ));
194- canvas->drawRect (SkRect::MakeWH (1 .5f * kWidth , 1 .5f * kHeight ), repeatPaint);
195- canvas->translate (1 .5f * kWidth + kPad , 0 );
216+ canvas->drawRect (SkRect::MakeWH (1 .5f *w , 1 .5f *h ), repeatPaint);
217+ canvas->translate (1 .5f *w + kPad , 0 );
196218
197219 // drawImageRect with kStrict
198- auto srcRect = SkRect::MakeXYWH (.25f * rectImgs[i]->width (),
199- .25f * rectImgs[i]->height (),
200- .50f * rectImgs[i]->width (),
201- .50f * rectImgs[i]->height ());
202- auto dstRect = SkRect::MakeXYWH (0 , 0 ,
203- .50f * rectImgs[i]->width (),
204- .50f * rectImgs[i]->height ());
205- canvas->drawImageRect (rectImgs[i], srcRect, dstRect, &plainPaint,
220+ auto srcRect = SkRect::MakeXYWH (.25f *w, .25f *h, .50f *w, .50f *h);
221+ auto dstRect = SkRect::MakeXYWH ( 0 , 0 , .50f *w, .50f *h);
222+ canvas->drawImageRect (gradImgs[i], srcRect, dstRect, &plainPaint,
206223 SkCanvas::kStrict_SrcRectConstraint );
207- canvas->translate (kWidth * .5f + kPad , 0 );
224+ canvas->translate (.5f *w + kPad , 0 );
208225 }
209226 canvas->restore ();
210- canvas->translate (0 , kPad + 1 .5f * kHeight * s);
227+ canvas->translate (0 , kPad + 1 .5f *h* s);
211228 }
212229 }
230+
231+ auto smallImg = this ->createRectangleTextureImg (context, kTopLeft_GrSurfaceOrigin ,
232+ this ->makeImagePixels (2 , ImageType::k2x2));
233+ static constexpr SkScalar kOutset = 25 .f ;
234+ canvas->translate (kOutset , kOutset );
235+ auto dstRect = SkRect::Make (smallImg->dimensions ()).makeOutset (kOutset , kOutset );
236+
237+ for (int fq = kNone_SkFilterQuality ; fq <= kLast_SkFilterQuality ; ++fq) {
238+ if (fq == kMedium_SkFilterQuality ) {
239+ // Medium is the same as Low for upscaling.
240+ continue ;
241+ }
242+ canvas->save ();
243+ for (int ty = 0 ; ty < kSkTileModeCount ; ++ty) {
244+ canvas->save ();
245+ for (int tx = 0 ; tx < kSkTileModeCount ; ++tx) {
246+ SkMatrix lm;
247+ lm.setRotate (45 .f , 1 , 1 );
248+ lm.postScale (6 .5f , 6 .5f );
249+ auto shader = smallImg->makeShader (static_cast <SkTileMode>(tx),
250+ static_cast <SkTileMode>(ty), &lm);
251+ SkPaint paint;
252+ paint.setShader (std::move (shader));
253+ paint.setFilterQuality (static_cast <SkFilterQuality>(fq));
254+ canvas->drawRect (dstRect, paint);
255+ canvas->translate (dstRect.width () + kPad , 0 );
256+ }
257+ canvas->restore ();
258+ canvas->translate (0 , dstRect.height () + kPad );
259+ }
260+ canvas->restore ();
261+ canvas->translate ((dstRect.width () + kPad )*kSkTileModeCount , 0 );
262+ }
263+
213264 return DrawResult::kOk ;
214265 }
215266
0 commit comments