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

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

Issue 956143002: Revert of Use an image generator to back SkPictureShader tiles. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « src/core/SkPictureShader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkPictureShader.h" 8 #include "SkPictureShader.h"
9 9
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
11 #include "SkBitmapProcShader.h" 11 #include "SkBitmapProcShader.h"
12 #include "SkCanvas.h" 12 #include "SkCanvas.h"
13 #include "SkImageGenerator.h"
14 #include "SkMatrixUtils.h" 13 #include "SkMatrixUtils.h"
15 #include "SkPicture.h" 14 #include "SkPicture.h"
16 #include "SkReadBuffer.h" 15 #include "SkReadBuffer.h"
17 #include "SkResourceCache.h" 16 #include "SkResourceCache.h"
18 17
19 #if SK_SUPPORT_GPU 18 #if SK_SUPPORT_GPU
20 #include "GrContext.h" 19 #include "GrContext.h"
21 #endif 20 #endif
22 21
23 namespace { 22 namespace {
24 static unsigned gBitmapSkaderKeyNamespaceLabel; 23 static unsigned gBitmapSkaderKeyNamespaceLabel;
25 24
26 class PictureImageGenerator : public SkImageGenerator {
27 public:
28 PictureImageGenerator(const SkPicture* picture,
29 const SkRect& pictureTile,
30 const SkISize& tileSize)
31 : fPicture(SkRef(picture))
32 , fPictureTile(pictureTile)
33 , fRasterTileInfo(SkImageInfo::MakeN32Premul(tileSize)) {}
34
35 protected:
36 virtual bool onGetInfo(SkImageInfo *info) SK_OVERRIDE {
37 *info = fRasterTileInfo;
38 return true;
39 }
40
41 virtual Result onGetPixels(const SkImageInfo& info, void *pixels, size_t row Bytes,
42 SkPMColor ctable[], int *ctableCount) SK_OVERRIDE {
43 if (info != fRasterTileInfo || SkToBool(ctable) || SkToBool(ctableCount) ) {
44 return kInvalidConversion;
45 }
46
47 SkSize tileScale = SkSize::Make(SkIntToScalar(info.width()) / fPictureTi le.width(),
48 SkIntToScalar(info.height()) / fPictureT ile.height());
49 SkBitmap tileBitmap;
50 if (!tileBitmap.installPixels(info, pixels, rowBytes)) {
51 return kInvalidParameters;
52 }
53 tileBitmap.eraseColor(SK_ColorTRANSPARENT);
54
55 // Always disable LCD text, since we can't assume our image will be opaq ue.
56 SkCanvas tileCanvas(tileBitmap, SkSurfaceProps(0, kUnknown_SkPixelGeomet ry));
57 tileCanvas.scale(tileScale.width(), tileScale.height());
58 tileCanvas.translate(-fPictureTile.x(), -fPictureTile.y());
59 tileCanvas.drawPicture(fPicture);
60
61 return kSuccess;
62 }
63
64 private:
65 SkAutoTUnref<const SkPicture> fPicture;
66 const SkRect fPictureTile;
67 const SkImageInfo fRasterTileInfo;
68 };
69
70 struct BitmapShaderKey : public SkResourceCache::Key { 25 struct BitmapShaderKey : public SkResourceCache::Key {
71 public: 26 public:
72 BitmapShaderKey(uint32_t pictureID, 27 BitmapShaderKey(uint32_t pictureID,
73 const SkRect& tile, 28 const SkRect& tile,
74 SkShader::TileMode tmx, 29 SkShader::TileMode tmx,
75 SkShader::TileMode tmy, 30 SkShader::TileMode tmy,
76 const SkSize& scale, 31 const SkSize& scale,
77 const SkMatrix& localMatrix) 32 const SkMatrix& localMatrix)
78 : fPictureID(pictureID) 33 : fPictureID(pictureID)
79 , fTile(tile) 34 , fTile(tile)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 size_t bytesUsed() const SK_OVERRIDE { 74 size_t bytesUsed() const SK_OVERRIDE {
120 return sizeof(fKey) + sizeof(SkShader) + fBitmapBytes; 75 return sizeof(fKey) + sizeof(SkShader) + fBitmapBytes;
121 } 76 }
122 77
123 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextShader ) { 78 static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextShader ) {
124 const BitmapShaderRec& rec = static_cast<const BitmapShaderRec&>(baseRec ); 79 const BitmapShaderRec& rec = static_cast<const BitmapShaderRec&>(baseRec );
125 SkAutoTUnref<SkShader>* result = reinterpret_cast<SkAutoTUnref<SkShader> *>(contextShader); 80 SkAutoTUnref<SkShader>* result = reinterpret_cast<SkAutoTUnref<SkShader> *>(contextShader);
126 81
127 result->reset(SkRef(rec.fShader.get())); 82 result->reset(SkRef(rec.fShader.get()));
128 83
129 // The bitmap shader is backed by an image generator, thus it can always re-generate its 84 SkBitmap tile;
130 // pixels if discarded. 85 rec.fShader.get()->asABitmap(&tile, NULL, NULL);
131 return true; 86 // FIXME: this doesn't protect the pixels from being discarded as soon a s we unlock.
87 // Should be handled via a pixel ref generator instead
88 // (https://code.google.com/p/skia/issues/detail?id=3220).
89 SkAutoLockPixels alp(tile, true);
90 return tile.getPixels() != NULL;
132 } 91 }
133 }; 92 };
134 93
94 static bool cache_try_alloc_pixels(SkBitmap* bitmap) {
95 SkBitmap::Allocator* allocator = SkResourceCache::GetAllocator();
96
97 return NULL != allocator
98 ? allocator->allocPixelRef(bitmap, NULL)
99 : bitmap->tryAllocPixels();
100 }
101
135 } // namespace 102 } // namespace
136 103
137 SkPictureShader::SkPictureShader(const SkPicture* picture, TileMode tmx, TileMod e tmy, 104 SkPictureShader::SkPictureShader(const SkPicture* picture, TileMode tmx, TileMod e tmy,
138 const SkMatrix* localMatrix, const SkRect* tile ) 105 const SkMatrix* localMatrix, const SkRect* tile )
139 : INHERITED(localMatrix) 106 : INHERITED(localMatrix)
140 , fPicture(SkRef(picture)) 107 , fPicture(SkRef(picture))
141 , fTile(tile ? *tile : picture->cullRect()) 108 , fTile(tile ? *tile : picture->cullRect())
142 , fTmx(tmx) 109 , fTmx(tmx)
143 , fTmy(tmy) { 110 , fTmy(tmy) {
144 } 111 }
145 112
113 SkPictureShader::~SkPictureShader() {
114 fPicture->unref();
115 }
116
146 SkPictureShader* SkPictureShader::Create(const SkPicture* picture, TileMode tmx, TileMode tmy, 117 SkPictureShader* SkPictureShader::Create(const SkPicture* picture, TileMode tmx, TileMode tmy,
147 const SkMatrix* localMatrix, const SkRe ct* tile) { 118 const SkMatrix* localMatrix, const SkRe ct* tile) {
148 if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) { 119 if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) {
149 return NULL; 120 return NULL;
150 } 121 }
151 return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy, localMatrix, tile)); 122 return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy, localMatrix, tile));
152 } 123 }
153 124
154 SkFlattenable* SkPictureShader::CreateProc(SkReadBuffer& buffer) { 125 SkFlattenable* SkPictureShader::CreateProc(SkReadBuffer& buffer) {
155 SkMatrix lm; 126 SkMatrix lm;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 SkAutoTUnref<SkShader> tileShader; 181 SkAutoTUnref<SkShader> tileShader;
211 BitmapShaderKey key(fPicture->uniqueID(), 182 BitmapShaderKey key(fPicture->uniqueID(),
212 fTile, 183 fTile,
213 fTmx, 184 fTmx,
214 fTmy, 185 fTmy,
215 tileScale, 186 tileScale,
216 this->getLocalMatrix()); 187 this->getLocalMatrix());
217 188
218 if (!SkResourceCache::Find(key, BitmapShaderRec::Visitor, &tileShader)) { 189 if (!SkResourceCache::Find(key, BitmapShaderRec::Visitor, &tileShader)) {
219 SkBitmap bm; 190 SkBitmap bm;
220 if (!SkInstallDiscardablePixelRef(SkNEW_ARGS(PictureImageGenerator, 191 bm.setInfo(SkImageInfo::MakeN32Premul(tileSize));
221 (fPicture, fTile, tileSize) ), &bm)) { 192 if (!cache_try_alloc_pixels(&bm)) {
222 return NULL; 193 return NULL;
223 } 194 }
195 bm.eraseColor(SK_ColorTRANSPARENT);
196
197 // Always disable LCD text, since we can't assume our image will be opaq ue.
198 SkCanvas canvas(bm, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
199
200 canvas.scale(tileScale.width(), tileScale.height());
201 canvas.translate(-fTile.x(), -fTile.y());
202 canvas.drawPicture(fPicture);
224 203
225 SkMatrix shaderMatrix = this->getLocalMatrix(); 204 SkMatrix shaderMatrix = this->getLocalMatrix();
226 shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height()); 205 shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
227 tileShader.reset(CreateBitmapShader(bm, fTmx, fTmy, &shaderMatrix)); 206 tileShader.reset(CreateBitmapShader(bm, fTmx, fTmy, &shaderMatrix));
228 207
229 SkResourceCache::Add(SkNEW_ARGS(BitmapShaderRec, (key, tileShader.get(), bm.getSize()))); 208 SkResourceCache::Add(SkNEW_ARGS(BitmapShaderRec, (key, tileShader.get(), bm.getSize())));
230 } 209 }
231 210
232 return tileShader.detach(); 211 return tileShader.detach();
233 } 212 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 fBitmapShaderContext->shadeSpan16(x, y, dstC, count); 273 fBitmapShaderContext->shadeSpan16(x, y, dstC, count);
295 } 274 }
296 275
297 #ifndef SK_IGNORE_TO_STRING 276 #ifndef SK_IGNORE_TO_STRING
298 void SkPictureShader::toString(SkString* str) const { 277 void SkPictureShader::toString(SkString* str) const {
299 static const char* gTileModeName[SkShader::kTileModeCount] = { 278 static const char* gTileModeName[SkShader::kTileModeCount] = {
300 "clamp", "repeat", "mirror" 279 "clamp", "repeat", "mirror"
301 }; 280 };
302 281
303 str->appendf("PictureShader: [%f:%f:%f:%f] ", 282 str->appendf("PictureShader: [%f:%f:%f:%f] ",
304 fPicture->cullRect().fLeft, 283 fPicture ? fPicture->cullRect().fLeft : 0,
305 fPicture->cullRect().fTop, 284 fPicture ? fPicture->cullRect().fTop : 0,
306 fPicture->cullRect().fRight, 285 fPicture ? fPicture->cullRect().fRight : 0,
307 fPicture->cullRect().fBottom); 286 fPicture ? fPicture->cullRect().fBottom : 0);
308 287
309 str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]); 288 str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
310 289
311 this->INHERITED::toString(str); 290 this->INHERITED::toString(str);
312 } 291 }
313 #endif 292 #endif
314 293
315 #if SK_SUPPORT_GPU 294 #if SK_SUPPORT_GPU
316 bool SkPictureShader::asFragmentProcessor(GrContext* context, const SkPaint& pai nt, 295 bool SkPictureShader::asFragmentProcessor(GrContext* context, const SkPaint& pai nt,
317 const SkMatrix& viewM, const SkMatrix* localMatrix, 296 const SkMatrix& viewM, const SkMatrix* localMatrix,
318 GrColor* paintColor, 297 GrColor* paintColor,
319 GrFragmentProcessor** fp) const { 298 GrFragmentProcessor** fp) const {
320 SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(viewM, localMatrix )); 299 SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(viewM, localMatrix ));
321 if (!bitmapShader) { 300 if (!bitmapShader) {
322 return false; 301 return false;
323 } 302 }
324 return bitmapShader->asFragmentProcessor(context, paint, viewM, NULL, paintC olor, fp); 303 return bitmapShader->asFragmentProcessor(context, paint, viewM, NULL, paintC olor, fp);
325 } 304 }
326 #else 305 #else
327 bool SkPictureShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMa trix&, 306 bool SkPictureShader::asFragmentProcessor(GrContext*, const SkPaint&, const SkMa trix&,
328 const SkMatrix*, GrColor*, 307 const SkMatrix*, GrColor*,
329 GrFragmentProcessor**) const { 308 GrFragmentProcessor**) const {
330 SkDEBUGFAIL("Should not call in GPU-less build"); 309 SkDEBUGFAIL("Should not call in GPU-less build");
331 return false; 310 return false;
332 } 311 }
333 #endif 312 #endif
OLDNEW
« no previous file with comments | « src/core/SkPictureShader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698