aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2014-09-04 07:24:18 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-04 07:24:18 -0700
commit274b4ba6bde67bb8b6d8f1721ef5d6d4294f2aa8 (patch)
tree444a5ea4c004e9e1ed6a04ae3b783d6b5abb5848 /src
parent5353bae113f98e044113ddf7df5ee26906e1be61 (diff)
Switch Layer Hoisting over to SkRecord backend
R=bsalomon@google.com TBR=bsalomon@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/540543002
Diffstat (limited to 'src')
-rw-r--r--src/core/SkPictureRangePlayback.cpp57
-rw-r--r--src/core/SkPictureRangePlayback.h41
-rw-r--r--src/core/SkPictureReplacementPlayback.cpp171
-rw-r--r--src/core/SkPictureReplacementPlayback.h86
-rw-r--r--src/gpu/GrLayerHoister.cpp20
-rw-r--r--src/gpu/GrRecordReplaceDraw.cpp2
-rw-r--r--src/gpu/SkGpuDevice.cpp18
7 files changed, 17 insertions, 378 deletions
diff --git a/src/core/SkPictureRangePlayback.cpp b/src/core/SkPictureRangePlayback.cpp
deleted file mode 100644
index b5e36d6f22..0000000000
--- a/src/core/SkPictureRangePlayback.cpp
+++ /dev/null
@@ -1,57 +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.
- */
-
-#include "SkCanvas.h"
-#include "SkPictureData.h"
-#include "SkPictureRangePlayback.h"
-
-void SkPictureRangePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) {
- AutoResetOpID aroi(this);
- SkASSERT(0 == fCurOffset);
-
- SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->size());
-
- if (0 != fStart || 0 != fStop) {
- reader.setOffset(fStart);
- uint32_t size;
- SkDEBUGCODE(DrawType op = ) ReadOpAndSize(&reader, &size);
- SkASSERT(SAVE_LAYER == op);
- reader.setOffset(fStart + size);
- }
-
- // Record this, so we can concat w/ it if we encounter a setMatrix()
- SkMatrix initialMatrix = canvas->getTotalMatrix();
-
- SkAutoCanvasRestore acr(canvas, false);
-
- while (!reader.eof()) {
- if (NULL != callback && callback->abortDrawing()) {
- return;
- }
-
- if (0 != fStart || 0 != fStop) {
- size_t offset = reader.offset();
- if (offset >= fStop) {
- SkDEBUGCODE(uint32_t size;)
- SkDEBUGCODE(DrawType op = ReadOpAndSize(&reader, &size);)
- SkASSERT(RESTORE == op);
- return;
- }
- }
-
- fCurOffset = reader.offset();
- uint32_t size;
- DrawType op = ReadOpAndSize(&reader, &size);
- if (NOOP == op) {
- // NOOPs are to be ignored - do not propagate them any further
- reader.setOffset(fCurOffset + size);
- continue;
- }
-
- this->handleOp(&reader, op, size, canvas, initialMatrix);
- }
-}
diff --git a/src/core/SkPictureRangePlayback.h b/src/core/SkPictureRangePlayback.h
deleted file mode 100644
index ee114bde13..0000000000
--- a/src/core/SkPictureRangePlayback.h
+++ /dev/null
@@ -1,41 +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 SkPictureRangePlayback_DEFINED
-#define SkPictureRangePlayback_DEFINED
-
-#include "SkPicturePlayback.h"
-
-// This version of picture playback plays all the operations between
-// a pair of start and stop values.
-// The opcode at 'start' should be a saveLayer while the opcode at
-// 'stop' should be a restore. Neither of those commands will be issued.
-// Since this class never uses the bounding box hierarchy, the base class'
-// useBBH setting is ignored.
-class SkPictureRangePlayback : public SkPicturePlayback {
-public:
- // Set both start & stop to 0 to disable draw limiting. Note that disabling
- // draw limiting isn't the same as using the base SkPicturePlayback object
- // since this class never uses the bounding box hierarchy information.
- SkPictureRangePlayback(const SkPicture* picture, size_t start, size_t stop)
- : INHERITED(picture)
- , fStart(start)
- , fStop(stop) {
- }
-
- virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*) SK_OVERRIDE;
-
-private:
- size_t fStart;
- size_t fStop;
-
- typedef SkPicturePlayback INHERITED;
-};
-
-
-#endif
diff --git a/src/core/SkPictureReplacementPlayback.cpp b/src/core/SkPictureReplacementPlayback.cpp
deleted file mode 100644
index 12498064e0..0000000000
--- a/src/core/SkPictureReplacementPlayback.cpp
+++ /dev/null
@@ -1,171 +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.
- */
-
-#include "SkCanvas.h"
-#include "SkPicture.h"
-#include "SkPictureData.h"
-#include "SkPictureReplacementPlayback.h"
-
-
-SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo*
-SkPictureReplacementPlayback::PlaybackReplacements::push() {
- SkDEBUGCODE(this->validate());
- return fReplacements.push();
-}
-
-void SkPictureReplacementPlayback::PlaybackReplacements::freeAll() {
- for (int i = 0; i < fReplacements.count(); ++i) {
- SkDELETE(fReplacements[i].fBM);
- }
- fReplacements.reset();
-}
-
-#ifdef SK_DEBUG
-void SkPictureReplacementPlayback::PlaybackReplacements::validate() const {
- // Check that the ranges are monotonically increasing and non-overlapping
- if (fReplacements.count() > 0) {
- SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop);
-
- for (int i = 1; i < fReplacements.count(); ++i) {
- SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop);
- SkASSERT(fReplacements[i - 1].fStop < fReplacements[i].fStart);
- }
- }
-}
-#endif
-
-// TODO: Replace with hash or pass in "lastLookedUp" hint
-SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo*
-SkPictureReplacementPlayback::PlaybackReplacements::lookupByStart(size_t start) {
- SkDEBUGCODE(this->validate());
- for (int i = 0; i < fReplacements.count(); ++i) {
- if (start == fReplacements[i].fStart) {
- return &fReplacements[i];
- } else if (start < fReplacements[i].fStart) {
- return NULL; // the ranges are monotonically increasing and non-overlapping
- }
- }
-
- return NULL;
-}
-
-bool SkPictureReplacementPlayback::replaceOps(SkPictureStateTree::Iterator* iter,
- SkReader32* reader,
- SkCanvas* canvas,
- const SkMatrix& initialMatrix) {
- if (NULL != fReplacements) {
- // Potentially replace a block of operations with a single drawBitmap call
- PlaybackReplacements::ReplacementInfo* temp =
- fReplacements->lookupByStart(reader->offset());
- if (NULL != temp) {
- SkASSERT(NULL != temp->fBM);
- SkASSERT(NULL != temp->fPaint);
- canvas->save();
- canvas->setMatrix(initialMatrix);
- SkRect src = SkRect::Make(temp->fSrcRect);
- SkRect dst = SkRect::MakeXYWH(temp->fPos.fX, temp->fPos.fY,
- temp->fSrcRect.width(),
- temp->fSrcRect.height());
- canvas->drawBitmapRectToRect(*temp->fBM, &src, dst, temp->fPaint);
- canvas->restore();
-
- if (iter->isValid()) {
- // This save is needed since the BBH will automatically issue
- // a restore to balanced the saveLayer we're skipping
- canvas->save();
-
- // At this point we know that the PictureStateTree was aiming
- // for some draw op within temp's saveLayer (although potentially
- // in a separate saveLayer nested inside it).
- // We need to skip all the operations inside temp's range
- // along with all the associated state changes but update
- // the state tree to the first operation outside temp's range.
-
- uint32_t skipTo;
- do {
- skipTo = iter->nextDraw();
- if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
- break;
- }
-
- if (skipTo <= temp->fStop) {
- reader->setOffset(skipTo);
- uint32_t size;
- DrawType op = ReadOpAndSize(reader, &size);
- // Since we are relying on the normal SkPictureStateTree
- // playback we need to convert any nested saveLayer calls
- // it may issue into saves (so that all its internal
- // restores will be balanced).
- if (SAVE_LAYER == op) {
- canvas->save();
- }
- }
- } while (skipTo <= temp->fStop);
-
- if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
- reader->setOffset(reader->size()); // skip to end
- return true;
- }
-
- reader->setOffset(skipTo);
- } else {
- reader->setOffset(temp->fStop);
- uint32_t size;
- SkDEBUGCODE(DrawType op = ) ReadOpAndSize(reader, &size);
- SkASSERT(RESTORE == op);
- }
-
- return true;
- }
- }
-
- return false;
-}
-
-void SkPictureReplacementPlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) {
- AutoResetOpID aroi(this);
- SkASSERT(0 == fCurOffset);
-
- SkPictureStateTree::Iterator it;
-
- if (!this->initIterator(&it, canvas, fActiveOpsList)) {
- return; // nothing to draw
- }
-
- SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->size());
-
- StepIterator(&it, &reader);
-
- // Record this, so we can concat w/ it if we encounter a setMatrix()
- SkMatrix initialMatrix = canvas->getTotalMatrix();
-
- SkAutoCanvasRestore acr(canvas, false);
-
- while (!reader.eof()) {
- if (NULL != callback && callback->abortDrawing()) {
- return;
- }
-
- if (this->replaceOps(&it, &reader, canvas, initialMatrix)) {
- continue;
- }
-
- fCurOffset = reader.offset();
- uint32_t size;
- DrawType op = ReadOpAndSize(&reader, &size);
- if (NOOP == op) {
- // NOOPs are to be ignored - do not propagate them any further
- SkipIterTo(&it, &reader, fCurOffset + size);
- continue;
- }
-
- this->handleOp(&reader, op, size, canvas, initialMatrix);
-
- StepIterator(&it, &reader);
- }
-}
diff --git a/src/core/SkPictureReplacementPlayback.h b/src/core/SkPictureReplacementPlayback.h
deleted file mode 100644
index 166a3bfbd3..0000000000
--- a/src/core/SkPictureReplacementPlayback.h
+++ /dev/null
@@ -1,86 +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 SkPictureReplacementPlayback_DEFINED
-#define SkPictureReplacementPlayback_DEFINED
-
-#include "SkPicturePlayback.h"
-
-// This playback class replaces complete "saveLayer ... restore" runs with a
-// single drawBitmap call.
-class SkPictureReplacementPlayback : public SkPicturePlayback {
-public:
- // PlaybackReplacements collects op ranges that can be replaced with
- // a single drawBitmap call (using a precomputed bitmap).
- class PlaybackReplacements {
- public:
- // All the operations between fStart and fStop (inclusive) will be replaced with
- // a single drawBitmap call using fPos, fBM and fPaint.
- // fPaint will be NULL if the picture's paint wasn't copyable
- struct ReplacementInfo {
- size_t fStart;
- size_t fStop;
- SkIPoint fPos;
- SkBitmap* fBM; // fBM is allocated so ReplacementInfo can remain POD
- const SkPaint* fPaint; // Note: this object doesn't own the paint
-
- SkIRect fSrcRect;
- };
-
- ~PlaybackReplacements() { this->freeAll(); }
-
- // Add a new replacement range. The replacement ranges should be
- // sorted in increasing order and non-overlapping (esp. no nested
- // saveLayers).
- ReplacementInfo* push();
-
- // look up a replacement range by its start offset
- ReplacementInfo* lookupByStart(size_t start);
-
- private:
- SkTDArray<ReplacementInfo> fReplacements;
-
- void freeAll();
-
-#ifdef SK_DEBUG
- void validate() const;
-#endif
- };
-
- // This class doesn't take ownership of either 'replacements' or 'activeOpsList'
- // The caller must guarantee they exist across any calls to 'draw'.
- // 'activeOpsList' can be NULL but in that case BBH acceleration will not
- // be used ('replacements' can be NULL too but that defeats the purpose
- // of using this class).
- SkPictureReplacementPlayback(const SkPicture* picture,
- PlaybackReplacements* replacements,
- const SkPicture::OperationList* activeOpsList)
- : INHERITED(picture)
- , fReplacements(replacements)
- , fActiveOpsList(activeOpsList) {
- }
-
- virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*) SK_OVERRIDE;
-
-private:
- PlaybackReplacements* fReplacements;
- const SkPicture::OperationList* fActiveOpsList;
-
- // This method checks if the current op pointed at by 'iter' and 'reader'
- // is within a replacement range. If so, it issues the drawBitmap call,
- // updates 'iter' and 'reader' to be after the restore operation, and
- // returns true. If the operation is not in a replacement range (and thus
- // needs to be drawn normally) false is returned.
- bool replaceOps(SkPictureStateTree::Iterator* iter,
- SkReader32* reader,
- SkCanvas* canvas,
- const SkMatrix& initialMatrix);
-
- typedef SkPicturePlayback INHERITED;
-};
-
-#endif
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp
index 2dfefcd3fe..2ed5b0ae80 100644
--- a/src/gpu/GrLayerHoister.cpp
+++ b/src/gpu/GrLayerHoister.cpp
@@ -7,8 +7,8 @@
#include "GrLayerCache.h"
#include "GrLayerHoister.h"
-#include "SkPictureRangePlayback.h"
#include "SkCanvas.h"
+#include "SkRecordDraw.h"
#include "SkSurface.h"
// Return true if any layers are suitable for hoisting
@@ -94,10 +94,8 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
atlasCanvas->translate(bound.fLeft, bound.fTop);
atlasCanvas->concat(layer->ctm());
- SkPictureRangePlayback rangePlayback(picture,
- layer->start(),
- layer->stop());
- rangePlayback.draw(atlasCanvas, NULL);
+ SkRecordPartialDraw(*picture->fRecord.get(), atlasCanvas, bound,
+ layer->start(), layer->stop());
atlasCanvas->restore();
}
@@ -111,9 +109,9 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
// Each non-atlased layer has its own GrTexture
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
- layer->texture()->asRenderTarget(),
- SkSurface::kStandard_TextRenderMode,
- SkSurface::kDontClear_RenderTargetFlag));
+ layer->texture()->asRenderTarget(),
+ SkSurface::kStandard_TextRenderMode,
+ SkSurface::kDontClear_RenderTargetFlag));
SkCanvas* layerCanvas = surface->getCanvas();
@@ -130,10 +128,8 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
layerCanvas->concat(layer->ctm());
- SkPictureRangePlayback rangePlayback(picture,
- layer->start(),
- layer->stop());
- rangePlayback.draw(layerCanvas, NULL);
+ SkRecordPartialDraw(*picture->fRecord.get(), layerCanvas, bound,
+ layer->start(), layer->stop());
layerCanvas->flush();
}
diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp
index 8291ccb828..ab5192680d 100644
--- a/src/gpu/GrRecordReplaceDraw.cpp
+++ b/src/gpu/GrRecordReplaceDraw.cpp
@@ -87,7 +87,7 @@ void GrRecordReplaceDraw(const SkRecord& record,
if (NULL != callback && callback->abortDrawing()) {
return;
}
- ri = replacements->lookupByStart(i, &searchStart);
+ ri = replacements->lookupByStart((uintptr_t)ops[i], &searchStart);
if (NULL != ri) {
draw_replacement_bitmap(ri, canvas);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 6a7748f88b..375d0e68b3 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -18,6 +18,7 @@
#include "GrLayerCache.h"
#include "GrLayerHoister.h"
#include "GrPictureUtils.h"
+#include "GrRecordReplaceDraw.h"
#include "GrStrokeInfo.h"
#include "GrTracing.h"
@@ -31,8 +32,7 @@
#include "SkPathEffect.h"
#include "SkPicture.h"
#include "SkPictureData.h"
-#include "SkPictureRangePlayback.h"
-#include "SkPictureReplacementPlayback.h"
+#include "SkRecord.h"
#include "SkRRect.h"
#include "SkStroke.h"
#include "SkSurface.h"
@@ -1875,7 +1875,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
return false;
}
- SkPictureReplacementPlayback::PlaybackReplacements replacements;
+ GrReplacements replacements;
SkTDArray<GrCachedLayer*> atlased, nonAtlased;
atlased.setReserve(gpuData->numSaveLayers());
@@ -1890,8 +1890,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
info.fRestoreOpID,
info.fOriginXform);
- SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
- replacements.push();
+ GrReplacements::ReplacementInfo* layerInfo = replacements.push();
layerInfo->fStart = info.fSaveLayerOpID;
layerInfo->fStop = info.fRestoreOpID;
layerInfo->fPos = info.fOffset;
@@ -1909,11 +1908,12 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
continue;
}
- layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so ReplacementInfo can be POD
+ SkBitmap bm;
wrap_texture(layer->texture(),
!layer->isAtlased() ? desc.fWidth : layer->texture()->width(),
!layer->isAtlased() ? desc.fHeight : layer->texture()->height(),
- layerInfo->fBM);
+ &bm);
+ layerInfo->fImage = SkImage::NewTexture(bm);
SkASSERT(info.fPaint);
layerInfo->fPaint = info.fPaint;
@@ -1936,9 +1936,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
GrLayerHoister::DrawLayers(picture, atlased, nonAtlased);
// Render the entire picture using new layers
- SkPictureReplacementPlayback playback(picture, &replacements, NULL);
-
- playback.draw(mainCanvas, NULL);
+ GrRecordReplaceDraw(*picture->fRecord, mainCanvas, picture->fBBH.get(), &replacements, NULL);
GrLayerHoister::UnlockLayers(fContext->getLayerCache(), picture);