Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 | 95 |
| 96 SkPictureShader::SkPictureShader(const SkPicture* picture, TileMode tmx, TileMod e tmy, | 96 SkPictureShader::SkPictureShader(const SkPicture* picture, TileMode tmx, TileMod e tmy, |
| 97 const SkMatrix* localMatrix, const SkRect* tile ) | 97 const SkMatrix* localMatrix, const SkRect* tile ) |
| 98 : INHERITED(localMatrix) | 98 : INHERITED(localMatrix) |
| 99 , fPicture(SkRef(picture)) | 99 , fPicture(SkRef(picture)) |
| 100 , fTile(tile ? *tile : picture->cullRect()) | 100 , fTile(tile ? *tile : picture->cullRect()) |
| 101 , fTmx(tmx) | 101 , fTmx(tmx) |
| 102 , fTmy(tmy) { | 102 , fTmy(tmy) { |
| 103 } | 103 } |
| 104 | 104 |
| 105 SkShader* SkPictureShader::Create(const SkPicture* picture, TileMode tmx, TileMo de tmy, | 105 sk_sp<SkShader> SkPictureShader::Make(const SkPicture* picture, TileMode tmx, Ti leMode tmy, |
| 106 const SkMatrix* localMatrix, const SkRe ct* tile) { | 106 const SkMatrix* localMatrix, const SkRect* tile) { |
| 107 if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) { | 107 if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) { |
| 108 return SkShader::CreateEmptyShader(); | 108 return SkShader::MakeEmptyShader(); |
| 109 } | 109 } |
| 110 return new SkPictureShader(picture, tmx, tmy, localMatrix, tile); | 110 return sk_sp<SkShader>(new SkPictureShader(picture, tmx, tmy, localMatrix, t ile)); |
| 111 } | 111 } |
| 112 | 112 |
| 113 SkFlattenable* SkPictureShader::CreateProc(SkReadBuffer& buffer) { | 113 SkFlattenable* SkPictureShader::CreateProc(SkReadBuffer& buffer) { |
| 114 SkMatrix lm; | 114 SkMatrix lm; |
| 115 buffer.readMatrix(&lm); | 115 buffer.readMatrix(&lm); |
| 116 TileMode mx = (TileMode)buffer.read32(); | 116 TileMode mx = (TileMode)buffer.read32(); |
| 117 TileMode my = (TileMode)buffer.read32(); | 117 TileMode my = (TileMode)buffer.read32(); |
| 118 SkRect tile; | 118 SkRect tile; |
| 119 buffer.readRect(&tile); | 119 buffer.readRect(&tile); |
| 120 | 120 |
| 121 SkAutoTUnref<SkPicture> picture; | 121 SkAutoTUnref<SkPicture> picture; |
| 122 | 122 |
| 123 if (buffer.isCrossProcess() && SkPicture::PictureIOSecurityPrecautionsEnable d()) { | 123 if (buffer.isCrossProcess() && SkPicture::PictureIOSecurityPrecautionsEnable d()) { |
| 124 if (buffer.isVersionLT(SkReadBuffer::kPictureShaderHasPictureBool_Versio n)) { | 124 if (buffer.isVersionLT(SkReadBuffer::kPictureShaderHasPictureBool_Versio n)) { |
| 125 // Older code blindly serialized pictures. We don't trust them. | 125 // Older code blindly serialized pictures. We don't trust them. |
| 126 buffer.validate(false); | 126 buffer.validate(false); |
| 127 return nullptr; | 127 return nullptr; |
| 128 } | 128 } |
| 129 // Newer code won't serialize pictures in disallow-cross-process-picture mode. | 129 // Newer code won't serialize pictures in disallow-cross-process-picture mode. |
| 130 // Assert that they didn't serialize anything except a false here. | 130 // Assert that they didn't serialize anything except a false here. |
| 131 buffer.validate(!buffer.readBool()); | 131 buffer.validate(!buffer.readBool()); |
| 132 } else { | 132 } else { |
| 133 // Old code always serialized the picture. New code writes a 'true' fir st if it did. | 133 // Old code always serialized the picture. New code writes a 'true' fir st if it did. |
| 134 if (buffer.isVersionLT(SkReadBuffer::kPictureShaderHasPictureBool_Versio n) || | 134 if (buffer.isVersionLT(SkReadBuffer::kPictureShaderHasPictureBool_Versio n) || |
| 135 buffer.readBool()) { | 135 buffer.readBool()) { |
| 136 picture.reset(SkPicture::CreateFromBuffer(buffer)); | 136 picture.reset(SkPicture::CreateFromBuffer(buffer)); |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 return SkPictureShader::Create(picture, mx, my, &lm, &tile); | 139 return SkPictureShader::Make(picture, mx, my, &lm, &tile).release(); |
| 140 } | 140 } |
| 141 | 141 |
| 142 void SkPictureShader::flatten(SkWriteBuffer& buffer) const { | 142 void SkPictureShader::flatten(SkWriteBuffer& buffer) const { |
| 143 buffer.writeMatrix(this->getLocalMatrix()); | 143 buffer.writeMatrix(this->getLocalMatrix()); |
| 144 buffer.write32(fTmx); | 144 buffer.write32(fTmx); |
| 145 buffer.write32(fTmy); | 145 buffer.write32(fTmy); |
| 146 buffer.writeRect(fTile); | 146 buffer.writeRect(fTile); |
| 147 | 147 |
| 148 // The deserialization code won't trust that our serialized picture is safe to deserialize. | 148 // The deserialization code won't trust that our serialized picture is safe to deserialize. |
| 149 // So write a 'false' telling it that we're not serializing a picture. | 149 // So write a 'false' telling it that we're not serializing a picture. |
| 150 if (buffer.isCrossProcess() && SkPicture::PictureIOSecurityPrecautionsEnable d()) { | 150 if (buffer.isCrossProcess() && SkPicture::PictureIOSecurityPrecautionsEnable d()) { |
| 151 buffer.writeBool(false); | 151 buffer.writeBool(false); |
| 152 } else { | 152 } else { |
| 153 buffer.writeBool(true); | 153 buffer.writeBool(true); |
| 154 fPicture->flatten(buffer); | 154 fPicture->flatten(buffer); |
| 155 } | 155 } |
| 156 } | 156 } |
| 157 | 157 |
| 158 SkShader* SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, const SkM atrix* localM, | 158 sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, con st SkMatrix* localM, |
| 159 const int maxTextureSize) const { | 159 const int maxTextureSize) const { |
| 160 SkASSERT(fPicture && !fPicture->cullRect().isEmpty()); | 160 SkASSERT(fPicture && !fPicture->cullRect().isEmpty()); |
| 161 | 161 |
| 162 SkMatrix m; | 162 SkMatrix m; |
| 163 m.setConcat(viewMatrix, this->getLocalMatrix()); | 163 m.setConcat(viewMatrix, this->getLocalMatrix()); |
| 164 if (localM) { | 164 if (localM) { |
| 165 m.preConcat(*localM); | 165 m.preConcat(*localM); |
| 166 } | 166 } |
| 167 | 167 |
| 168 // Use a rotation-invariant scale | 168 // Use a rotation-invariant scale |
| 169 SkPoint scale; | 169 SkPoint scale; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 196 } | 196 } |
| 197 } | 197 } |
| 198 #endif | 198 #endif |
| 199 | 199 |
| 200 #ifdef SK_SUPPORT_LEGACY_PICTURESHADER_ROUNDING | 200 #ifdef SK_SUPPORT_LEGACY_PICTURESHADER_ROUNDING |
| 201 const SkISize tileSize = scaledSize.toRound(); | 201 const SkISize tileSize = scaledSize.toRound(); |
| 202 #else | 202 #else |
| 203 const SkISize tileSize = scaledSize.toCeil(); | 203 const SkISize tileSize = scaledSize.toCeil(); |
| 204 #endif | 204 #endif |
| 205 if (tileSize.isEmpty()) { | 205 if (tileSize.isEmpty()) { |
| 206 return SkShader::CreateEmptyShader(); | 206 return SkShader::MakeEmptyShader(); |
| 207 } | 207 } |
| 208 | 208 |
| 209 // The actual scale, compensating for rounding & clamping. | 209 // The actual scale, compensating for rounding & clamping. |
| 210 const SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fTil e.width(), | 210 const SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fTil e.width(), |
| 211 SkIntToScalar(tileSize.height()) / fTi le.height()); | 211 SkIntToScalar(tileSize.height()) / fTi le.height()); |
| 212 | 212 |
| 213 SkAutoTUnref<SkShader> tileShader; | 213 SkAutoTUnref<SkShader> tileShader; |
|
f(malita)
2016/03/08 15:50:35
Looks like this local should also get the sk_sp fa
reed1
2016/03/08 20:17:15
Doh! Done.
| |
| 214 BitmapShaderKey key(fPicture->uniqueID(), | 214 BitmapShaderKey key(fPicture->uniqueID(), |
| 215 fTile, | 215 fTile, |
| 216 fTmx, | 216 fTmx, |
| 217 fTmy, | 217 fTmy, |
| 218 tileScale, | 218 tileScale, |
| 219 this->getLocalMatrix()); | 219 this->getLocalMatrix()); |
| 220 | 220 |
| 221 if (!SkResourceCache::Find(key, BitmapShaderRec::Visitor, &tileShader)) { | 221 if (!SkResourceCache::Find(key, BitmapShaderRec::Visitor, &tileShader)) { |
| 222 SkMatrix tileMatrix; | 222 SkMatrix tileMatrix; |
| 223 tileMatrix.setRectToRect(fTile, SkRect::MakeIWH(tileSize.width(), tileSi ze.height()), | 223 tileMatrix.setRectToRect(fTile, SkRect::MakeIWH(tileSize.width(), tileSi ze.height()), |
| 224 SkMatrix::kFill_ScaleToFit); | 224 SkMatrix::kFill_ScaleToFit); |
| 225 | 225 |
| 226 SkAutoTUnref<SkImage> tileImage( | 226 SkAutoTUnref<SkImage> tileImage( |
| 227 SkImage::NewFromPicture(fPicture, tileSize, &tileMatrix, nullptr)); | 227 SkImage::NewFromPicture(fPicture, tileSize, &tileMatrix, nullptr)); |
| 228 if (!tileImage) { | 228 if (!tileImage) { |
| 229 return nullptr; | 229 return nullptr; |
| 230 } | 230 } |
| 231 | 231 |
| 232 SkMatrix shaderMatrix = this->getLocalMatrix(); | 232 SkMatrix shaderMatrix = this->getLocalMatrix(); |
| 233 shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height()); | 233 shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height()); |
| 234 tileShader.reset(tileImage->newShader(fTmx, fTmy, &shaderMatrix)); | 234 tileShader.reset(tileImage->newShader(fTmx, fTmy, &shaderMatrix)); |
| 235 | 235 |
| 236 const SkImageInfo tileInfo = SkImageInfo::MakeN32Premul(tileSize); | 236 const SkImageInfo tileInfo = SkImageInfo::MakeN32Premul(tileSize); |
| 237 SkResourceCache::Add(new BitmapShaderRec(key, tileShader.get(), | 237 SkResourceCache::Add(new BitmapShaderRec(key, tileShader.get(), |
| 238 tileInfo.getSafeSize(tileInfo.m inRowBytes()))); | 238 tileInfo.getSafeSize(tileInfo.m inRowBytes()))); |
| 239 } | 239 } |
| 240 | 240 |
| 241 return tileShader.detach(); | 241 return sk_sp<SkShader>(tileShader.detach()); |
| 242 } | 242 } |
| 243 | 243 |
| 244 size_t SkPictureShader::onContextSize(const ContextRec&) const { | 244 size_t SkPictureShader::onContextSize(const ContextRec&) const { |
| 245 return sizeof(PictureShaderContext); | 245 return sizeof(PictureShaderContext); |
| 246 } | 246 } |
| 247 | 247 |
| 248 SkShader::Context* SkPictureShader::onCreateContext(const ContextRec& rec, void* storage) const { | 248 SkShader::Context* SkPictureShader::onCreateContext(const ContextRec& rec, void* storage) const { |
| 249 SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec. fLocalMatrix)); | 249 sk_sp<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalM atrix)); |
| 250 if (nullptr == bitmapShader.get()) { | 250 if (!bitmapShader) { |
| 251 return nullptr; | 251 return nullptr; |
| 252 } | 252 } |
| 253 return PictureShaderContext::Create(storage, *this, rec, bitmapShader); | 253 return PictureShaderContext::Create(storage, *this, rec, bitmapShader); |
| 254 } | 254 } |
| 255 | 255 |
| 256 //////////////////////////////////////////////////////////////////////////////// ///////// | 256 //////////////////////////////////////////////////////////////////////////////// ///////// |
| 257 | 257 |
| 258 SkShader::Context* SkPictureShader::PictureShaderContext::Create(void* storage, | 258 SkShader::Context* SkPictureShader::PictureShaderContext::Create(void* storage, |
| 259 const SkPictureShader& shader, const ContextRec& rec, SkShade r* bitmapShader) { | 259 const SkPictureShader& shader, const ContextRec& rec, |
| 260 sk_sp<SkShader> bitmapShader) { | |
| 260 PictureShaderContext* ctx = new (storage) PictureShaderContext(shader, rec, bitmapShader); | 261 PictureShaderContext* ctx = new (storage) PictureShaderContext(shader, rec, bitmapShader); |
|
f(malita)
2016/03/08 15:50:35
std::move(bitmapShader)
| |
| 261 if (nullptr == ctx->fBitmapShaderContext) { | 262 if (nullptr == ctx->fBitmapShaderContext) { |
| 262 ctx->~PictureShaderContext(); | 263 ctx->~PictureShaderContext(); |
| 263 ctx = nullptr; | 264 ctx = nullptr; |
| 264 } | 265 } |
| 265 return ctx; | 266 return ctx; |
| 266 } | 267 } |
| 267 | 268 |
| 268 SkPictureShader::PictureShaderContext::PictureShaderContext( | 269 SkPictureShader::PictureShaderContext::PictureShaderContext( |
| 269 const SkPictureShader& shader, const ContextRec& rec, SkShader* bitmapSh ader) | 270 const SkPictureShader& shader, const ContextRec& rec, sk_sp<SkShader> bi tmapShader) |
| 270 : INHERITED(shader, rec) | 271 : INHERITED(shader, rec) |
| 271 , fBitmapShader(SkRef(bitmapShader)) | 272 , fBitmapShader(bitmapShader) |
|
f(malita)
2016/03/08 15:50:35
ditto
reed1
2016/03/08 20:17:15
Done, but I think I had to change the subsequent r
| |
| 272 { | 273 { |
| 273 fBitmapShaderContextStorage = sk_malloc_throw(bitmapShader->contextSize(rec) ); | 274 fBitmapShaderContextStorage = sk_malloc_throw(bitmapShader->contextSize(rec) ); |
| 274 fBitmapShaderContext = bitmapShader->createContext(rec, fBitmapShaderContext Storage); | 275 fBitmapShaderContext = bitmapShader->createContext(rec, fBitmapShaderContext Storage); |
| 275 //if fBitmapShaderContext is null, we are invalid | 276 //if fBitmapShaderContext is null, we are invalid |
| 276 } | 277 } |
| 277 | 278 |
| 278 SkPictureShader::PictureShaderContext::~PictureShaderContext() { | 279 SkPictureShader::PictureShaderContext::~PictureShaderContext() { |
| 279 if (fBitmapShaderContext) { | 280 if (fBitmapShaderContext) { |
| 280 fBitmapShaderContext->~Context(); | 281 fBitmapShaderContext->~Context(); |
| 281 } | 282 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 318 #if SK_SUPPORT_GPU | 319 #if SK_SUPPORT_GPU |
| 319 const GrFragmentProcessor* SkPictureShader::asFragmentProcessor( | 320 const GrFragmentProcessor* SkPictureShader::asFragmentProcessor( |
| 320 GrContext* context, | 321 GrContext* context, |
| 321 const SkMatrix& viewM, | 322 const SkMatrix& viewM, |
| 322 const SkMatrix* localMatrix, | 323 const SkMatrix* localMatrix, |
| 323 SkFilterQuality fq) const { | 324 SkFilterQuality fq) const { |
| 324 int maxTextureSize = 0; | 325 int maxTextureSize = 0; |
| 325 if (context) { | 326 if (context) { |
| 326 maxTextureSize = context->caps()->maxTextureSize(); | 327 maxTextureSize = context->caps()->maxTextureSize(); |
| 327 } | 328 } |
| 328 SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(viewM, localMatrix , maxTextureSize)); | 329 sk_sp<SkShader> bitmapShader(this->refBitmapShader(viewM, localMatrix, maxTe xtureSize)); |
| 329 if (!bitmapShader) { | 330 if (!bitmapShader) { |
| 330 return nullptr; | 331 return nullptr; |
| 331 } | 332 } |
| 332 return bitmapShader->asFragmentProcessor(context, viewM, nullptr, fq); | 333 return bitmapShader->asFragmentProcessor(context, viewM, nullptr, fq); |
| 333 } | 334 } |
| 334 #endif | 335 #endif |
| OLD | NEW |