From c090c647e48f8f9adc199fe715c773a33980f1d4 Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Tue, 16 May 2017 10:39:06 -0400 Subject: move files out of private, and fix up callers to IWYU Realized that a pending CL needed to add (yet another) private type to SkRecords.h, but w/o this CL I'd be forced to move that header also into private. This change frees us up to not have transitive exposure for types that need to be recorded. Bug: skia: Change-Id: Id79f1c2e44ba85e063c1360cf96c92de6397ca2b Reviewed-on: https://skia-review.googlesource.com/17031 Commit-Queue: Mike Reed Reviewed-by: Mike Klein --- fuzz/FilterFuzz.cpp | 1 + fuzz/FuzzCanvas.cpp | 1 + gm/distantclip.cpp | 1 + gm/filterfastbounds.cpp | 1 + gm/multipicturedraw.cpp | 1 + gm/picture.cpp | 1 + gm/pictureimagegenerator.cpp | 1 + gn/core.gni | 4 +- include/core/SkPictureRecorder.h | 4 +- include/private/SkMiniRecorder.h | 57 ------- include/private/SkRecords.h | 356 --------------------------------------- samplecode/GMSampleView.cpp | 1 + samplecode/SampleFilterFuzz.cpp | 1 + src/core/SkMiniRecorder.h | 57 +++++++ src/core/SkPictureRecorder.cpp | 8 +- src/core/SkRecords.h | 356 +++++++++++++++++++++++++++++++++++++++ tests/ImageGeneratorTest.cpp | 1 + tests/ImageIsOpaqueTest.cpp | 1 + tests/RecordingXfermodeTest.cpp | 1 + 19 files changed, 434 insertions(+), 420 deletions(-) delete mode 100644 include/private/SkMiniRecorder.h delete mode 100644 include/private/SkRecords.h create mode 100644 src/core/SkMiniRecorder.h create mode 100644 src/core/SkRecords.h diff --git a/fuzz/FilterFuzz.cpp b/fuzz/FilterFuzz.cpp index cf65701d36..b2d99b771b 100644 --- a/fuzz/FilterFuzz.cpp +++ b/fuzz/FilterFuzz.cpp @@ -39,6 +39,7 @@ #include "SkPictureRecorder.h" #include "SkPoint3.h" #include "SkRandom.h" +#include "SkRegion.h" #include "SkTableColorFilter.h" #include "SkTileImageFilter.h" #include "SkTypeface.h" diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp index 3796812012..aec9173a16 100644 --- a/fuzz/FuzzCanvas.cpp +++ b/fuzz/FuzzCanvas.cpp @@ -54,6 +54,7 @@ #include "SkPictureImageFilter.h" #include "SkRRectsGaussianEdgeMaskFilter.h" #include "SkTableColorFilter.h" +#include "SkTextBlob.h" #include "SkTileImageFilter.h" #include "SkXfermodeImageFilter.h" diff --git a/gm/distantclip.cpp b/gm/distantclip.cpp index 24fbacaf4d..fa752659a5 100644 --- a/gm/distantclip.cpp +++ b/gm/distantclip.cpp @@ -8,6 +8,7 @@ #include "gm.h" #include "SkCanvas.h" +#include "SkPath.h" #include "SkPicture.h" #include "SkPictureRecorder.h" diff --git a/gm/filterfastbounds.cpp b/gm/filterfastbounds.cpp index 5102b863c2..ad042aca49 100644 --- a/gm/filterfastbounds.cpp +++ b/gm/filterfastbounds.cpp @@ -11,6 +11,7 @@ #include "SkDropShadowImageFilter.h" #include "SkImageSource.h" #include "SkOffsetImageFilter.h" +#include "SkPath.h" #include "SkPictureImageFilter.h" #include "SkPictureRecorder.h" #include "SkRandom.h" diff --git a/gm/multipicturedraw.cpp b/gm/multipicturedraw.cpp index fe2281ae20..b18fb8a53b 100644 --- a/gm/multipicturedraw.cpp +++ b/gm/multipicturedraw.cpp @@ -10,6 +10,7 @@ #include "SkColorFilter.h" #include "SkMultiPictureDraw.h" +#include "SkPath.h" #include "SkPictureRecorder.h" #include "SkSurface.h" diff --git a/gm/picture.cpp b/gm/picture.cpp index 72d4159aa9..5b3cdfb66c 100644 --- a/gm/picture.cpp +++ b/gm/picture.cpp @@ -7,6 +7,7 @@ #include "gm.h" #include "SkPaint.h" +#include "SkPath.h" #include "SkPictureRecorder.h" static sk_sp make_picture() { diff --git a/gm/pictureimagegenerator.cpp b/gm/pictureimagegenerator.cpp index a54fa643b9..4e465d157a 100644 --- a/gm/pictureimagegenerator.cpp +++ b/gm/pictureimagegenerator.cpp @@ -12,6 +12,7 @@ #include "SkGradientShader.h" #include "SkImageGenerator.h" #include "SkPaint.h" +#include "SkPath.h" #include "SkPathOps.h" #include "SkPicture.h" #include "SkPictureRecorder.h" diff --git a/gn/core.gni b/gn/core.gni index 1d88821f7d..5566ddebdd 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -207,6 +207,7 @@ skia_core_sources = [ "$_src/core/SkMipMap.cpp", "$_src/core/SkMipMap.h", "$_src/core/SkMiniRecorder.cpp", + "$_src/core/SkMiniRecorder.h", "$_src/core/SkModeColorFilter.cpp", "$_src/core/SkMultiPictureDraw.cpp", "$_src/core/SkNextID.h", @@ -271,6 +272,7 @@ skia_core_sources = [ "$_src/core/SkReader32.h", "$_src/core/SkRecord.cpp", "$_src/core/SkRecords.cpp", + "$_src/core/SkRecords.h", "$_src/core/SkRecordDraw.cpp", "$_src/core/SkRecordOpts.cpp", "$_src/core/SkRecordOpts.h", @@ -456,10 +458,8 @@ skia_core_sources = [ "$_include/private/SkFloatingPoint.h", "$_include/private/SkMalloc.h", "$_include/private/SkMessageBus.h", - "$_include/private/SkMiniRecorder.h", "$_include/private/SkMutex.h", "$_include/private/SkOnce.h", - "$_include/private/SkRecords.h", "$_include/private/SkSemaphore.h", "$_include/private/SkShadowFlags.h", "$_include/private/SkSpinlock.h", diff --git a/include/core/SkPictureRecorder.h b/include/core/SkPictureRecorder.h index d898b91cca..09839cba5e 100644 --- a/include/core/SkPictureRecorder.h +++ b/include/core/SkPictureRecorder.h @@ -8,7 +8,6 @@ #ifndef SkPictureRecorder_DEFINED #define SkPictureRecorder_DEFINED -#include "../private/SkMiniRecorder.h" #include "SkBBHFactory.h" #include "SkPicture.h" #include "SkRefCnt.h" @@ -22,6 +21,7 @@ namespace android { class GrContext; class SkCanvas; class SkDrawable; +class SkMiniRecorder; class SkPictureRecord; class SkRecord; class SkRecorder; @@ -116,7 +116,7 @@ private: sk_sp fBBH; std::unique_ptr fRecorder; sk_sp fRecord; - SkMiniRecorder fMiniRecorder; + std::unique_ptr fMiniRecorder; typedef SkNoncopyable INHERITED; }; diff --git a/include/private/SkMiniRecorder.h b/include/private/SkMiniRecorder.h deleted file mode 100644 index fd1e8f624d..0000000000 --- a/include/private/SkMiniRecorder.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkMiniRecorder_DEFINED -#define SkMiniRecorder_DEFINED - -#include "SkRecords.h" -#include "SkScalar.h" -#include "SkTypes.h" -class SkCanvas; - -// Records small pictures, but only a limited subset of the canvas API, and may fail. -class SkMiniRecorder : SkNoncopyable { -public: - SkMiniRecorder(); - ~SkMiniRecorder(); - - // Try to record an op. Returns false on failure. - bool drawPath(const SkPath&, const SkPaint&); - bool drawRect(const SkRect&, const SkPaint&); - bool drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint&); - - // Detach anything we've recorded as a picture, resetting this SkMiniRecorder. - // If cull is nullptr we'll calculate it. - sk_sp detachAsPicture(const SkRect* cull); - - // Flush anything we've recorded to the canvas, resetting this SkMiniRecorder. - // This is logically the same as but rather more efficient than: - // sk_sp pic(this->detachAsPicture(nullptr)); - // pic->playback(canvas); - void flushAndReset(SkCanvas*); - -private: - enum class State { - kEmpty, - kDrawPath, - kDrawRect, - kDrawTextBlob, - }; - - State fState; - - template - struct Max { static const size_t val = A > B ? A : B; }; - - static const size_t kInlineStorage = - Max::val>::val; - SkAlignedSStorage fBuffer; -}; - -#endif//SkMiniRecorder_DEFINED diff --git a/include/private/SkRecords.h b/include/private/SkRecords.h deleted file mode 100644 index 6af4aad3f5..0000000000 --- a/include/private/SkRecords.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkRecords_DEFINED -#define SkRecords_DEFINED - -#include "SkData.h" -#include "SkCanvas.h" -#include "SkDrawable.h" -#include "SkImage.h" -#include "SkImageFilter.h" -#include "SkMatrix.h" -#include "SkPath.h" -#include "SkPicture.h" -#include "SkRect.h" -#include "SkRegion.h" -#include "SkRRect.h" -#include "SkRSXform.h" -#include "SkString.h" -#include "SkTextBlob.h" -#include "SkVertices.h" - -// Windows.h, will pull in all of the GDI defines. GDI #defines -// DrawText to DrawTextA or DrawTextW, but SkRecord has a struct -// called DrawText. Since this file does not use GDI, undefing -// DrawText makes things less confusing. -#ifdef DrawText -#undef DrawText -#endif - -namespace SkRecords { - -// A list of all the types of canvas calls we can record. -// Each of these is reified into a struct below. -// -// (We're using the macro-of-macro trick here to do several different things with the same list.) -// -// We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords -// types polymorphically. (See SkRecord::Record::{visit,mutate} for an example.) -// -// Order doesn't technically matter here, but the compiler can generally generate better code if -// you keep them semantically grouped, especially the Draws. It's also nice to leave NoOp at 0. -#define SK_RECORD_TYPES(M) \ - M(NoOp) \ - M(Restore) \ - M(Save) \ - M(SaveLayer) \ - M(SetMatrix) \ - M(Translate) \ - M(Concat) \ - M(ClipPath) \ - M(ClipRRect) \ - M(ClipRect) \ - M(ClipRegion) \ - M(DrawArc) \ - M(DrawDrawable) \ - M(DrawImage) \ - M(DrawImageLattice) \ - M(DrawImageRect) \ - M(DrawImageNine) \ - M(DrawDRRect) \ - M(DrawOval) \ - M(DrawPaint) \ - M(DrawPath) \ - M(DrawPatch) \ - M(DrawPicture) \ - M(DrawPoints) \ - M(DrawPosText) \ - M(DrawPosTextH) \ - M(DrawText) \ - M(DrawTextOnPath) \ - M(DrawTextRSXform) \ - M(DrawRRect) \ - M(DrawRect) \ - M(DrawRegion) \ - M(DrawTextBlob) \ - M(DrawAtlas) \ - M(DrawVertices) \ - M(DrawAnnotation) - -// Defines SkRecords::Type, an enum of all record types. -#define ENUM(T) T##_Type, -enum Type { SK_RECORD_TYPES(ENUM) }; -#undef ENUM - -#define ACT_AS_PTR(ptr) \ - operator T*() const { return ptr; } \ - T* operator->() const { return ptr; } - -// An Optional doesn't own the pointer's memory, but may need to destroy non-POD data. -template -class Optional : SkNoncopyable { -public: - Optional() : fPtr(nullptr) {} - Optional(T* ptr) : fPtr(ptr) {} - Optional(Optional&& o) : fPtr(o.fPtr) { - o.fPtr = nullptr; - } - ~Optional() { if (fPtr) fPtr->~T(); } - - ACT_AS_PTR(fPtr) -private: - T* fPtr; -}; - -// Like Optional, but ptr must not be NULL. -template -class Adopted : SkNoncopyable { -public: - Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); } - Adopted(Adopted* source) { - // Transfer ownership from source to this. - fPtr = source->fPtr; - source->fPtr = NULL; - } - ~Adopted() { if (fPtr) fPtr->~T(); } - - ACT_AS_PTR(fPtr) -private: - T* fPtr; -}; - -// PODArray doesn't own the pointer's memory, and we assume the data is POD. -template -class PODArray { -public: - PODArray() {} - PODArray(T* ptr) : fPtr(ptr) {} - // Default copy and assign. - - ACT_AS_PTR(fPtr) -private: - T* fPtr; -}; - -#undef ACT_AS_PTR - -// SkPath::getBounds() isn't thread safe unless we precache the bounds in a singlethreaded context. -// SkPath::cheapComputeDirection() is similar. -// Recording is a convenient time to cache these, or we can delay it to between record and playback. -struct PreCachedPath : public SkPath { - PreCachedPath() {} - PreCachedPath(const SkPath& path); -}; - -// Like SkPath::getBounds(), SkMatrix::getType() isn't thread safe unless we precache it. -// This may not cover all SkMatrices used by the picture (e.g. some could be hiding in a shader). -struct TypedMatrix : public SkMatrix { - TypedMatrix() {} - TypedMatrix(const SkMatrix& matrix); -}; - -enum Tags { - kDraw_Tag = 1, // May draw something (usually named DrawFoo). - kHasImage_Tag = 2, // Contains an SkImage or SkBitmap. - kHasText_Tag = 4, // Contains text. - kHasPaint_Tag = 8, // May have an SkPaint field, at least optionally. - - kDrawWithPaint_Tag = kDraw_Tag | kHasPaint_Tag, -}; - -// A macro to make it a little easier to define a struct that can be stored in SkRecord. -#define RECORD(T, tags, ...) \ -struct T { \ - static const Type kType = T##_Type; \ - static const int kTags = tags; \ - __VA_ARGS__; \ -}; - -RECORD(NoOp, 0); -RECORD(Restore, 0, - SkIRect devBounds; - TypedMatrix matrix); -RECORD(Save, 0); - -RECORD(SaveLayer, kHasPaint_Tag, - Optional bounds; - Optional paint; - sk_sp backdrop; - sk_sp clipMask; - Optional clipMatrix; - SkCanvas::SaveLayerFlags saveLayerFlags); - -RECORD(SetMatrix, 0, - TypedMatrix matrix); -RECORD(Concat, 0, - TypedMatrix matrix); - -RECORD(Translate, 0, - SkScalar dx; - SkScalar dy); - -struct ClipOpAndAA { - ClipOpAndAA() {} - ClipOpAndAA(SkClipOp op, bool aa) : fOp(static_cast(op)), fAA(aa) {} - - SkClipOp op() const { return static_cast(fOp); } - bool aa() const { return fAA != 0; } - -private: - unsigned fOp : 31; // This really only needs to be 3, but there's no win today to do so. - unsigned fAA : 1; // MSVC won't pack an enum with an bool, so we call this an unsigned. -}; -static_assert(sizeof(ClipOpAndAA) == 4, "ClipOpAndAASize"); - -RECORD(ClipPath, 0, - SkIRect devBounds; - PreCachedPath path; - ClipOpAndAA opAA); -RECORD(ClipRRect, 0, - SkIRect devBounds; - SkRRect rrect; - ClipOpAndAA opAA); -RECORD(ClipRect, 0, - SkIRect devBounds; - SkRect rect; - ClipOpAndAA opAA); -RECORD(ClipRegion, 0, - SkIRect devBounds; - SkRegion region; - SkClipOp op); - -// While not strictly required, if you have an SkPaint, it's fastest to put it first. -RECORD(DrawArc, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - SkRect oval; - SkScalar startAngle; - SkScalar sweepAngle; - unsigned useCenter); -RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - SkRRect outer; - SkRRect inner); -RECORD(DrawDrawable, kDraw_Tag, - Optional matrix; - SkRect worstCaseBounds; - int32_t index); -RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, - Optional paint; - sk_sp image; - SkScalar left; - SkScalar top); -RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, - Optional paint; - sk_sp image; - int xCount; - PODArray xDivs; - int yCount; - PODArray yDivs; - int flagCount; - PODArray flags; - SkIRect src; - SkRect dst); -RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, - Optional paint; - sk_sp image; - Optional src; - SkRect dst; - SkCanvas::SrcRectConstraint constraint); -RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, - Optional paint; - sk_sp image; - SkIRect center; - SkRect dst); -RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - SkRect oval); -RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag, - SkPaint paint); -RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - PreCachedPath path); -RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag, - Optional paint; - sk_sp picture; - TypedMatrix matrix); -RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - SkCanvas::PointMode mode; - unsigned count; - SkPoint* pts); -RECORD(DrawPosText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, - SkPaint paint; - PODArray text; - size_t byteLength; - PODArray pos); -RECORD(DrawPosTextH, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, - SkPaint paint; - PODArray text; - unsigned byteLength; - SkScalar y; - PODArray xpos); -RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - SkRRect rrect); -RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - SkRect rect); -RECORD(DrawRegion, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - SkRegion region); -RECORD(DrawText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, - SkPaint paint; - PODArray text; - size_t byteLength; - SkScalar x; - SkScalar y); -RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, - SkPaint paint; - sk_sp blob; - SkScalar x; - SkScalar y); -RECORD(DrawTextOnPath, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, - SkPaint paint; - PODArray text; - size_t byteLength; - PreCachedPath path; - TypedMatrix matrix); -RECORD(DrawTextRSXform, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, - SkPaint paint; - PODArray text; - size_t byteLength; - PODArray xforms; - Optional cull); -RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - PODArray cubics; - PODArray colors; - PODArray texCoords; - SkBlendMode bmode); -RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, - Optional paint; - sk_sp atlas; - PODArray xforms; - PODArray texs; - PODArray colors; - int count; - SkBlendMode mode; - Optional cull); -RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag, - SkPaint paint; - sk_sp vertices; - SkBlendMode bmode); -RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548 - SkRect rect; - SkString key; - sk_sp value); -#undef RECORD - -} // namespace SkRecords - -#endif//SkRecords_DEFINED diff --git a/samplecode/GMSampleView.cpp b/samplecode/GMSampleView.cpp index 19cbcc8b57..ffa33cedfc 100644 --- a/samplecode/GMSampleView.cpp +++ b/samplecode/GMSampleView.cpp @@ -6,6 +6,7 @@ */ #include "GMSampleView.h" +#include "SkData.h" GMSampleView::GMSampleView(GM* gm) : fShowSize(false), fGM(gm) {} diff --git a/samplecode/SampleFilterFuzz.cpp b/samplecode/SampleFilterFuzz.cpp index 3690612870..7254192fe5 100644 --- a/samplecode/SampleFilterFuzz.cpp +++ b/samplecode/SampleFilterFuzz.cpp @@ -39,6 +39,7 @@ #include "SkPictureRecorder.h" #include "SkPoint3.h" #include "SkRandom.h" +#include "SkRegion.h" #include "SkTableColorFilter.h" #include "SkTileImageFilter.h" #include "SkTypeface.h" diff --git a/src/core/SkMiniRecorder.h b/src/core/SkMiniRecorder.h new file mode 100644 index 0000000000..fd1e8f624d --- /dev/null +++ b/src/core/SkMiniRecorder.h @@ -0,0 +1,57 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkMiniRecorder_DEFINED +#define SkMiniRecorder_DEFINED + +#include "SkRecords.h" +#include "SkScalar.h" +#include "SkTypes.h" +class SkCanvas; + +// Records small pictures, but only a limited subset of the canvas API, and may fail. +class SkMiniRecorder : SkNoncopyable { +public: + SkMiniRecorder(); + ~SkMiniRecorder(); + + // Try to record an op. Returns false on failure. + bool drawPath(const SkPath&, const SkPaint&); + bool drawRect(const SkRect&, const SkPaint&); + bool drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint&); + + // Detach anything we've recorded as a picture, resetting this SkMiniRecorder. + // If cull is nullptr we'll calculate it. + sk_sp detachAsPicture(const SkRect* cull); + + // Flush anything we've recorded to the canvas, resetting this SkMiniRecorder. + // This is logically the same as but rather more efficient than: + // sk_sp pic(this->detachAsPicture(nullptr)); + // pic->playback(canvas); + void flushAndReset(SkCanvas*); + +private: + enum class State { + kEmpty, + kDrawPath, + kDrawRect, + kDrawTextBlob, + }; + + State fState; + + template + struct Max { static const size_t val = A > B ? A : B; }; + + static const size_t kInlineStorage = + Max::val>::val; + SkAlignedSStorage fBuffer; +}; + +#endif//SkMiniRecorder_DEFINED diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp index 7abb12bfa7..a37cd4826c 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 "SkMiniRecorder.h" #include "SkPictureRecorder.h" #include "SkRecord.h" #include "SkRecordDraw.h" @@ -18,7 +19,8 @@ SkPictureRecorder::SkPictureRecorder() { fActivelyRecording = false; - fRecorder.reset(new SkRecorder(nullptr, SkRect::MakeEmpty(), &fMiniRecorder)); + fMiniRecorder.reset(new SkMiniRecorder); + fRecorder.reset(new SkRecorder(nullptr, SkRect::MakeEmpty(), fMiniRecorder.get())); } SkPictureRecorder::~SkPictureRecorder() {} @@ -42,7 +44,7 @@ SkCanvas* SkPictureRecorder::beginRecording(const SkRect& userCullRect, SkRecorder::DrawPictureMode dpm = (recordFlags & kPlaybackDrawPicture_RecordFlag) ? SkRecorder::Playback_DrawPictureMode : SkRecorder::Record_DrawPictureMode; - fRecorder->reset(fRecord.get(), cullRect, dpm, &fMiniRecorder); + fRecorder->reset(fRecord.get(), cullRect, dpm, fMiniRecorder.get()); fActivelyRecording = true; return this->getRecordingCanvas(); } @@ -56,7 +58,7 @@ sk_sp SkPictureRecorder::finishRecordingAsPicture(uint32_t finishFlag fRecorder->restoreToCount(1); // If we were missing any restores, add them now. if (fRecord->count() == 0) { - auto pic = fMiniRecorder.detachAsPicture(fBBH ? nullptr : &fCullRect); + auto pic = fMiniRecorder->detachAsPicture(fBBH ? nullptr : &fCullRect); fBBH.reset(nullptr); return pic; } diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h new file mode 100644 index 0000000000..6af4aad3f5 --- /dev/null +++ b/src/core/SkRecords.h @@ -0,0 +1,356 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkRecords_DEFINED +#define SkRecords_DEFINED + +#include "SkData.h" +#include "SkCanvas.h" +#include "SkDrawable.h" +#include "SkImage.h" +#include "SkImageFilter.h" +#include "SkMatrix.h" +#include "SkPath.h" +#include "SkPicture.h" +#include "SkRect.h" +#include "SkRegion.h" +#include "SkRRect.h" +#include "SkRSXform.h" +#include "SkString.h" +#include "SkTextBlob.h" +#include "SkVertices.h" + +// Windows.h, will pull in all of the GDI defines. GDI #defines +// DrawText to DrawTextA or DrawTextW, but SkRecord has a struct +// called DrawText. Since this file does not use GDI, undefing +// DrawText makes things less confusing. +#ifdef DrawText +#undef DrawText +#endif + +namespace SkRecords { + +// A list of all the types of canvas calls we can record. +// Each of these is reified into a struct below. +// +// (We're using the macro-of-macro trick here to do several different things with the same list.) +// +// We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords +// types polymorphically. (See SkRecord::Record::{visit,mutate} for an example.) +// +// Order doesn't technically matter here, but the compiler can generally generate better code if +// you keep them semantically grouped, especially the Draws. It's also nice to leave NoOp at 0. +#define SK_RECORD_TYPES(M) \ + M(NoOp) \ + M(Restore) \ + M(Save) \ + M(SaveLayer) \ + M(SetMatrix) \ + M(Translate) \ + M(Concat) \ + M(ClipPath) \ + M(ClipRRect) \ + M(ClipRect) \ + M(ClipRegion) \ + M(DrawArc) \ + M(DrawDrawable) \ + M(DrawImage) \ + M(DrawImageLattice) \ + M(DrawImageRect) \ + M(DrawImageNine) \ + M(DrawDRRect) \ + M(DrawOval) \ + M(DrawPaint) \ + M(DrawPath) \ + M(DrawPatch) \ + M(DrawPicture) \ + M(DrawPoints) \ + M(DrawPosText) \ + M(DrawPosTextH) \ + M(DrawText) \ + M(DrawTextOnPath) \ + M(DrawTextRSXform) \ + M(DrawRRect) \ + M(DrawRect) \ + M(DrawRegion) \ + M(DrawTextBlob) \ + M(DrawAtlas) \ + M(DrawVertices) \ + M(DrawAnnotation) + +// Defines SkRecords::Type, an enum of all record types. +#define ENUM(T) T##_Type, +enum Type { SK_RECORD_TYPES(ENUM) }; +#undef ENUM + +#define ACT_AS_PTR(ptr) \ + operator T*() const { return ptr; } \ + T* operator->() const { return ptr; } + +// An Optional doesn't own the pointer's memory, but may need to destroy non-POD data. +template +class Optional : SkNoncopyable { +public: + Optional() : fPtr(nullptr) {} + Optional(T* ptr) : fPtr(ptr) {} + Optional(Optional&& o) : fPtr(o.fPtr) { + o.fPtr = nullptr; + } + ~Optional() { if (fPtr) fPtr->~T(); } + + ACT_AS_PTR(fPtr) +private: + T* fPtr; +}; + +// Like Optional, but ptr must not be NULL. +template +class Adopted : SkNoncopyable { +public: + Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); } + Adopted(Adopted* source) { + // Transfer ownership from source to this. + fPtr = source->fPtr; + source->fPtr = NULL; + } + ~Adopted() { if (fPtr) fPtr->~T(); } + + ACT_AS_PTR(fPtr) +private: + T* fPtr; +}; + +// PODArray doesn't own the pointer's memory, and we assume the data is POD. +template +class PODArray { +public: + PODArray() {} + PODArray(T* ptr) : fPtr(ptr) {} + // Default copy and assign. + + ACT_AS_PTR(fPtr) +private: + T* fPtr; +}; + +#undef ACT_AS_PTR + +// SkPath::getBounds() isn't thread safe unless we precache the bounds in a singlethreaded context. +// SkPath::cheapComputeDirection() is similar. +// Recording is a convenient time to cache these, or we can delay it to between record and playback. +struct PreCachedPath : public SkPath { + PreCachedPath() {} + PreCachedPath(const SkPath& path); +}; + +// Like SkPath::getBounds(), SkMatrix::getType() isn't thread safe unless we precache it. +// This may not cover all SkMatrices used by the picture (e.g. some could be hiding in a shader). +struct TypedMatrix : public SkMatrix { + TypedMatrix() {} + TypedMatrix(const SkMatrix& matrix); +}; + +enum Tags { + kDraw_Tag = 1, // May draw something (usually named DrawFoo). + kHasImage_Tag = 2, // Contains an SkImage or SkBitmap. + kHasText_Tag = 4, // Contains text. + kHasPaint_Tag = 8, // May have an SkPaint field, at least optionally. + + kDrawWithPaint_Tag = kDraw_Tag | kHasPaint_Tag, +}; + +// A macro to make it a little easier to define a struct that can be stored in SkRecord. +#define RECORD(T, tags, ...) \ +struct T { \ + static const Type kType = T##_Type; \ + static const int kTags = tags; \ + __VA_ARGS__; \ +}; + +RECORD(NoOp, 0); +RECORD(Restore, 0, + SkIRect devBounds; + TypedMatrix matrix); +RECORD(Save, 0); + +RECORD(SaveLayer, kHasPaint_Tag, + Optional bounds; + Optional paint; + sk_sp backdrop; + sk_sp clipMask; + Optional clipMatrix; + SkCanvas::SaveLayerFlags saveLayerFlags); + +RECORD(SetMatrix, 0, + TypedMatrix matrix); +RECORD(Concat, 0, + TypedMatrix matrix); + +RECORD(Translate, 0, + SkScalar dx; + SkScalar dy); + +struct ClipOpAndAA { + ClipOpAndAA() {} + ClipOpAndAA(SkClipOp op, bool aa) : fOp(static_cast(op)), fAA(aa) {} + + SkClipOp op() const { return static_cast(fOp); } + bool aa() const { return fAA != 0; } + +private: + unsigned fOp : 31; // This really only needs to be 3, but there's no win today to do so. + unsigned fAA : 1; // MSVC won't pack an enum with an bool, so we call this an unsigned. +}; +static_assert(sizeof(ClipOpAndAA) == 4, "ClipOpAndAASize"); + +RECORD(ClipPath, 0, + SkIRect devBounds; + PreCachedPath path; + ClipOpAndAA opAA); +RECORD(ClipRRect, 0, + SkIRect devBounds; + SkRRect rrect; + ClipOpAndAA opAA); +RECORD(ClipRect, 0, + SkIRect devBounds; + SkRect rect; + ClipOpAndAA opAA); +RECORD(ClipRegion, 0, + SkIRect devBounds; + SkRegion region; + SkClipOp op); + +// While not strictly required, if you have an SkPaint, it's fastest to put it first. +RECORD(DrawArc, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + SkRect oval; + SkScalar startAngle; + SkScalar sweepAngle; + unsigned useCenter); +RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + SkRRect outer; + SkRRect inner); +RECORD(DrawDrawable, kDraw_Tag, + Optional matrix; + SkRect worstCaseBounds; + int32_t index); +RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, + Optional paint; + sk_sp image; + SkScalar left; + SkScalar top); +RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, + Optional paint; + sk_sp image; + int xCount; + PODArray xDivs; + int yCount; + PODArray yDivs; + int flagCount; + PODArray flags; + SkIRect src; + SkRect dst); +RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, + Optional paint; + sk_sp image; + Optional src; + SkRect dst; + SkCanvas::SrcRectConstraint constraint); +RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, + Optional paint; + sk_sp image; + SkIRect center; + SkRect dst); +RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + SkRect oval); +RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag, + SkPaint paint); +RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + PreCachedPath path); +RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag, + Optional paint; + sk_sp picture; + TypedMatrix matrix); +RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + SkCanvas::PointMode mode; + unsigned count; + SkPoint* pts); +RECORD(DrawPosText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, + SkPaint paint; + PODArray text; + size_t byteLength; + PODArray pos); +RECORD(DrawPosTextH, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, + SkPaint paint; + PODArray text; + unsigned byteLength; + SkScalar y; + PODArray xpos); +RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + SkRRect rrect); +RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + SkRect rect); +RECORD(DrawRegion, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + SkRegion region); +RECORD(DrawText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, + SkPaint paint; + PODArray text; + size_t byteLength; + SkScalar x; + SkScalar y); +RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, + SkPaint paint; + sk_sp blob; + SkScalar x; + SkScalar y); +RECORD(DrawTextOnPath, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, + SkPaint paint; + PODArray text; + size_t byteLength; + PreCachedPath path; + TypedMatrix matrix); +RECORD(DrawTextRSXform, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, + SkPaint paint; + PODArray text; + size_t byteLength; + PODArray xforms; + Optional cull); +RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + PODArray cubics; + PODArray colors; + PODArray texCoords; + SkBlendMode bmode); +RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, + Optional paint; + sk_sp atlas; + PODArray xforms; + PODArray texs; + PODArray colors; + int count; + SkBlendMode mode; + Optional cull); +RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag, + SkPaint paint; + sk_sp vertices; + SkBlendMode bmode); +RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548 + SkRect rect; + SkString key; + sk_sp value); +#undef RECORD + +} // namespace SkRecords + +#endif//SkRecords_DEFINED diff --git a/tests/ImageGeneratorTest.cpp b/tests/ImageGeneratorTest.cpp index d79b434e35..3d82534717 100644 --- a/tests/ImageGeneratorTest.cpp +++ b/tests/ImageGeneratorTest.cpp @@ -6,6 +6,7 @@ */ #include "SkData.h" +#include "SkCanvas.h" #include "SkGraphics.h" #include "SkImageGenerator.h" #include "Test.h" diff --git a/tests/ImageIsOpaqueTest.cpp b/tests/ImageIsOpaqueTest.cpp index 81f1d76609..bf3dea6334 100644 --- a/tests/ImageIsOpaqueTest.cpp +++ b/tests/ImageIsOpaqueTest.cpp @@ -12,6 +12,7 @@ #if SK_SUPPORT_GPU #include "GrContext.h" #endif +#include "SkCanvas.h" #include "SkColorSpace_Base.h" #include "SkImage.h" #include "SkSurface.h" diff --git a/tests/RecordingXfermodeTest.cpp b/tests/RecordingXfermodeTest.cpp index db4262c7e9..20dccc6cc2 100644 --- a/tests/RecordingXfermodeTest.cpp +++ b/tests/RecordingXfermodeTest.cpp @@ -7,6 +7,7 @@ #include "Test.h" +#include "../include/core/SkBitmap.h" #include "../include/core/SkCanvas.h" #include "../include/core/SkPicture.h" #include "../include/core/SkStream.h" -- cgit v1.2.3