Chromium Code Reviews| Index: src/core/SkPictureRecorder.cpp |
| diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp |
| index 5631a081d4a049c398f884e2644f6f8702597a93..8e7c7f3b06477240fa38a6298132ed93cecf579b 100644 |
| --- a/src/core/SkPictureRecorder.cpp |
| +++ b/src/core/SkPictureRecorder.cpp |
| @@ -8,6 +8,7 @@ |
| #include "SkBigPicture.h" |
| #include "SkData.h" |
| #include "SkDrawable.h" |
| +#include "SkImage.h" |
| #include "SkPictureRecorder.h" |
| #include "SkPictureUtils.h" |
| #include "SkRecord.h" |
| @@ -16,6 +17,54 @@ |
| #include "SkRecordedDrawable.h" |
| #include "SkRecorder.h" |
| #include "SkTypes.h" |
| +#include "SkTLogic.h" |
| + |
| +namespace SkRecords { |
| + |
| + struct OptimizeFor { |
| + GrContext* fCtx; |
| + |
| + // A few ops have a top-level SkImage: |
| + void operator()(DrawAtlas* op) { this->make_texture(&op->atlas); } |
| + void operator()(DrawImage* op) { this->make_texture(&op->image); } |
| + void operator()(DrawImageNine* op) { this->make_texture(&op->image); } |
| + void operator()(DrawImageRect* op) { this->make_texture(&op->image); } |
| + void make_texture(sk_sp<const SkImage>* img) const { |
| + *img = (*img)->makeTextureImage(fCtx); |
| + } |
| + |
| + // Some ops have a paint, some have an optional paint. |
| + // Either way, get back a pointer. |
| + static SkPaint* AsPtr(SkPaint& p) { return &p; } |
| + static SkPaint* AsPtr(SkRecords::Optional<SkPaint>& p) { return p; } |
| + |
| + // For all other types of ops, look for images inside the paint. |
| + template <typename T> |
| + SK_WHEN(T::kTags & kHasPaint_Tag, void) operator()(T* op) { |
| + SkMatrix matrix; |
| + SkShader::TileMode xy[2]; |
| + |
| + if (auto paint = AsPtr(op->paint)) |
| + if (auto shader = paint->getShader()) |
| + if (auto image = shader->isAImage(&matrix, xy)) { |
| + paint->setShader(image->makeTextureImage(fCtx)->makeShader(xy[0], xy[1], &matrix)); |
| + } |
| + |
| + // TODO: re-build compose shaders |
| + } |
| + |
| + // Control ops, etc. Nothing to do for these. |
| + template <typename T> |
| + SK_WHEN(!(T::kTags & kHasPaint_Tag), void) operator()(T*) {} |
| + }; |
| + |
| +} // namespace SkRecords |
| + |
| +static void optimize_for(GrContext* ctx, SkRecord* record) { |
| + for (int i = 0; ctx && i < record->count(); i++) { |
|
djsollen
2016/08/02 12:37:56
don't you want to avoid this loop if ctx == nullpt
|
| + record->mutate(i, SkRecords::OptimizeFor{ctx}); |
| + } |
| +} |
| SkPictureRecorder::SkPictureRecorder() { |
| fActivelyRecording = false; |
| @@ -63,6 +112,7 @@ sk_sp<SkPicture> SkPictureRecorder::finishRecordingAsPicture(uint32_t finishFlag |
| // TODO: delay as much of this work until just before first playback? |
| SkRecordOptimize(fRecord); |
| + optimize_for(fGrContextToOptimizeFor, fRecord); |
| if (fRecord->count() == 0) { |
| if (finishFlags & kReturnNullForEmpty_FinishFlag) { |
| @@ -123,6 +173,7 @@ sk_sp<SkDrawable> SkPictureRecorder::finishRecordingAsDrawable(uint32_t finishFl |
| fRecorder->restoreToCount(1); // If we were missing any restores, add them now. |
| SkRecordOptimize(fRecord); |
| + optimize_for(fGrContextToOptimizeFor, fRecord); |
| if (fRecord->count() == 0) { |
| if (finishFlags & kReturnNullForEmpty_FinishFlag) { |