LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkMiniRecorder.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 50 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 44 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2015 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 "SkCanvas.h"
       9             : #include "SkTLazy.h"
      10             : #include "SkMiniRecorder.h"
      11             : #include "SkOnce.h"
      12             : #include "SkPicture.h"
      13             : #include "SkPictureCommon.h"
      14             : #include "SkRecordDraw.h"
      15             : #include "SkTextBlob.h"
      16             : 
      17             : using namespace SkRecords;
      18             : 
      19           0 : class SkEmptyPicture final : public SkPicture {
      20             : public:
      21           0 :     void playback(SkCanvas*, AbortCallback*) const override { }
      22             : 
      23           0 :     size_t approximateBytesUsed() const override { return sizeof(*this); }
      24           0 :     int    approximateOpCount()   const override { return 0; }
      25           0 :     SkRect cullRect()             const override { return SkRect::MakeEmpty(); }
      26           0 :     int    numSlowPaths()         const override { return 0; }
      27           0 :     bool   willPlayBackBitmaps()  const override { return false; }
      28             : };
      29             : 
      30             : template <typename T>
      31           0 : class SkMiniPicture final : public SkPicture {
      32             : public:
      33           0 :     SkMiniPicture(SkRect cull, T* op) : fCull(cull) {
      34           0 :         memcpy(&fOp, op, sizeof(fOp));  // We take ownership of op's guts.
      35           0 :     }
      36             : 
      37           0 :     void playback(SkCanvas* c, AbortCallback*) const override {
      38           0 :         SkRecords::Draw(c, nullptr, nullptr, 0, nullptr)(fOp);
      39           0 :     }
      40             : 
      41           0 :     size_t approximateBytesUsed() const override { return sizeof(*this); }
      42           0 :     int    approximateOpCount()   const override { return 1; }
      43           0 :     SkRect cullRect()             const override { return fCull; }
      44           0 :     bool   willPlayBackBitmaps()  const override { return SkBitmapHunter()(fOp); }
      45           0 :     int    numSlowPaths()         const override {
      46           0 :         SkPathCounter counter;
      47           0 :         counter(fOp);
      48           0 :         return counter.fNumSlowPathsAndDashEffects;
      49             :     }
      50             : 
      51             : private:
      52             :     SkRect fCull;
      53             :     T      fOp;
      54             : };
      55             : 
      56             : 
      57           0 : SkMiniRecorder::SkMiniRecorder() : fState(State::kEmpty) {}
      58           0 : SkMiniRecorder::~SkMiniRecorder() {
      59           0 :     if (fState != State::kEmpty) {
      60             :         // We have internal state pending.
      61             :         // Detaching then deleting a picture is an easy way to clean up.
      62           0 :         (void)this->detachAsPicture(SkRect::MakeEmpty());
      63             :     }
      64           0 :     SkASSERT(fState == State::kEmpty);
      65           0 : }
      66             : 
      67             : #define TRY_TO_STORE(Type, ...)                    \
      68             :     if (fState != State::kEmpty) { return false; } \
      69             :     fState = State::k##Type;                       \
      70             :     new (fBuffer.get()) Type{__VA_ARGS__};         \
      71             :     return true
      72             : 
      73           0 : bool SkMiniRecorder::drawRect(const SkRect& rect, const SkPaint& paint) {
      74           0 :     TRY_TO_STORE(DrawRect, paint, rect);
      75             : }
      76             : 
      77           0 : bool SkMiniRecorder::drawPath(const SkPath& path, const SkPaint& paint) {
      78           0 :     TRY_TO_STORE(DrawPath, paint, path);
      79             : }
      80             : 
      81           0 : bool SkMiniRecorder::drawTextBlob(const SkTextBlob* b, SkScalar x, SkScalar y, const SkPaint& p) {
      82           0 :     TRY_TO_STORE(DrawTextBlob, p, sk_ref_sp(b), x, y);
      83             : }
      84             : #undef TRY_TO_STORE
      85             : 
      86             : 
      87           0 : sk_sp<SkPicture> SkMiniRecorder::detachAsPicture(const SkRect& cull) {
      88             : #define CASE(Type)              \
      89             :     case State::k##Type:        \
      90             :         fState = State::kEmpty; \
      91             :         return sk_make_sp<SkMiniPicture<Type>>(cull, reinterpret_cast<Type*>(fBuffer.get()))
      92             : 
      93             :     static SkOnce once;
      94             :     static SkPicture* empty;
      95             : 
      96           0 :     switch (fState) {
      97             :         case State::kEmpty:
      98           0 :             once([]{ empty = new SkEmptyPicture; });
      99           0 :             return sk_ref_sp(empty);
     100           0 :         CASE(DrawPath);
     101           0 :         CASE(DrawRect);
     102           0 :         CASE(DrawTextBlob);
     103             :     }
     104           0 :     SkASSERT(false);
     105           0 :     return nullptr;
     106             : #undef CASE
     107             : }
     108             : 
     109           0 : void SkMiniRecorder::flushAndReset(SkCanvas* canvas) {
     110             : #define CASE(Type)                                                  \
     111             :     case State::k##Type: {                                          \
     112             :         fState = State::kEmpty;                                     \
     113             :         Type* op = reinterpret_cast<Type*>(fBuffer.get());          \
     114             :         SkRecords::Draw(canvas, nullptr, nullptr, 0, nullptr)(*op); \
     115             :         op->~Type();                                                \
     116             :     } return
     117             : 
     118           0 :     switch (fState) {
     119           0 :         case State::kEmpty: return;
     120           0 :         CASE(DrawPath);
     121           0 :         CASE(DrawRect);
     122           0 :         CASE(DrawTextBlob);
     123             :     }
     124           0 :     SkASSERT(false);
     125             : #undef CASE
     126             : }

Generated by: LCOV version 1.13