Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/core/SkPictureShader.cpp

Issue 221923007: Initial picture shader implementation (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Win build fix + SkShader factory. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "SkPictureShader.h"
9
10 #include "SkBitmap.h"
11 #include "SkBitmapProcShader.h"
12 #include "SkCanvas.h"
13 #include "SkPicture.h"
14 #include "SkReadBuffer.h"
15
16 #if SK_SUPPORT_GPU
17 #include "GrContext.h"
18 #endif
19
20 SkPictureShader::SkPictureShader(SkPicture* picture, TileMode tmx, TileMode tmy)
21 : fPicture(picture)
22 , fTmx(tmx)
23 , fTmy(tmy) {
24 SkSafeRef(fPicture);
25 }
26
27 SkPictureShader::SkPictureShader(SkReadBuffer& buffer)
28 : INHERITED(buffer) {
29 fTmx = static_cast<SkShader::TileMode>(buffer.read32());
30 fTmy = static_cast<SkShader::TileMode>(buffer.read32());
31 if (buffer.readBool()) {
32 fPicture = SkPicture::CreateFromBuffer(buffer);
33 } else {
34 fPicture = NULL;
35 }
36 }
37
38 SkPictureShader::~SkPictureShader() {
39 SkSafeUnref(fPicture);
40 }
41
42 void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
43 this->INHERITED::flatten(buffer);
44
45 buffer.write32(fTmx);
46 buffer.write32(fTmy);
47 buffer.writeBool(fPicture != NULL);
robertphillips 2014/04/02 18:15:35 NULL != ?
f(malita) 2014/04/07 15:06:24 Done.
48 if (fPicture) {
49 fPicture->flatten(buffer);
50 }
51 }
52
53 bool SkPictureShader::buildBitmapShader(const SkMatrix& matrix) const {
54 if (!fPicture || (0 == fPicture->width() && 0 == fPicture->height())) {
55 return false;
56 }
57
58 SkMatrix m;
robertphillips 2014/04/02 18:15:35 this->
59 if (hasLocalMatrix()) {
robertphillips 2014/04/02 18:15:35 this->
60 m.setConcat(matrix, getLocalMatrix());
61 } else {
62 m = matrix;
63 }
64
65 // Rotation-invariant scale
66 float xScale = sqrtf(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.getSke wX());
67 float yScale = sqrtf(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.getSke wY());
reed1 2014/04/07 14:03:15 SkScalarSqrt
f(malita) 2014/04/07 15:06:24 Done.
68 SkSize mappedSize = SkSize::Make(xScale * fPicture->width(), yScale * fPictu re->height());
69
70 SkISize tileSize = mappedSize.toRound();
71 if (tileSize.isEmpty()) {
72 return false;
73 }
74
75 // The actual scale, compensating for rounding.
76 SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fPicture-> width(),
77 SkIntToScalar(tileSize.height()) / fPicture- >height());
78
79 if (!fCachedShader || tileScale != fCachedTileScale) {
80 SkBitmap bm;
81 if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) {
82 return false;
83 }
84 bm.eraseColor(SK_ColorTRANSPARENT);
85
86 SkCanvas canvas(bm);
87 canvas.scale(tileScale.width(), tileScale.height());
88 canvas.drawPicture(*fPicture);
89
90 fCachedShader.reset(CreateBitmapShader(bm, fTmx, fTmy));
91 fCachedTileScale = tileScale;
92 }
93
94 SkMatrix shaderMatrix = getLocalMatrix();
95 shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
96 fCachedShader->setLocalMatrix(shaderMatrix);
97
98 return true;
99 }
100
101 bool SkPictureShader::setContext(const SkBitmap& device,
102 const SkPaint& paint,
103 const SkMatrix& matrix) {
robertphillips 2014/04/02 18:15:35 this->
104 if (!buildBitmapShader(matrix)) {
105 return false;
106 }
107
108 if (!this->INHERITED::setContext(device, paint, matrix)) {
109 return false;
110 }
111
112 SkASSERT(fCachedShader);
113 if (!fCachedShader->setContext(device, paint, matrix)) {
114 this->INHERITED::endContext();
115 return false;
116 }
117
118 return true;
119 }
120
121 void SkPictureShader::endContext() {
122 SkASSERT(fCachedShader);
123 fCachedShader->endContext();
124
125 this->INHERITED::endContext();
126 }
127
128 uint32_t SkPictureShader::getFlags() {
robertphillips 2014/04/02 18:15:35 NULL !=
f(malita) 2014/04/07 15:06:24 Done.
129 if (fCachedShader) {
130 return fCachedShader->getFlags();
131 }
132 return 0;
133 }
134
135 SkShader::ShadeProc SkPictureShader::asAShadeProc(void** ctx) {
136 if (fCachedShader) {
137 return fCachedShader->asAShadeProc(ctx);
138 }
139 return NULL;
140 }
141
142 void SkPictureShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
143 SkASSERT(fCachedShader);
144 fCachedShader->shadeSpan(x, y, dstC, count);
145 }
146
147 void SkPictureShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
148 SkASSERT(fCachedShader);
149 fCachedShader->shadeSpan16(x, y, dstC, count);
150 }
151
152 #ifndef SK_IGNORE_TO_STRING
153 void SkPictureShader::toString(SkString* str) const {
154 static const char* gTileModeName[SkShader::kTileModeCount] = {
155 "clamp", "repeat", "mirror"
156 };
157
158 str->appendf("PictureShader: [%d:%d] ",
159 fPicture ? fPicture->width() : 0,
160 fPicture ? fPicture->height() : 0);
161
162 str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
163
164 this->INHERITED::toString(str);
165 }
166 #endif
167
168 #if SK_SUPPORT_GPU
169 GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& pai nt) const {
robertphillips 2014/04/02 18:15:35 this->
170 if (!buildBitmapShader(context->getMatrix())) {
171 return NULL;
172 }
173 SkASSERT(fCachedShader);
174 return fCachedShader->asNewEffect(context, paint);
175 }
176 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698