3 * Copyright 2012 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
9 #include "SkBBoxHierarchyRecord.h"
10 #include "SkPictureStateTree.h"
12 SkBBoxHierarchyRecord::SkBBoxHierarchyRecord(const SkISize& size,
15 : INHERITED(size, recordFlags) {
16 fStateTree = SkNEW(SkPictureStateTree);
17 fBoundingHierarchy = h;
18 fBoundingHierarchy->ref();
19 fBoundingHierarchy->setClient(this);
22 void SkBBoxHierarchyRecord::handleBBox(const SkRect& bounds) {
25 SkPictureStateTree::Draw* draw = fStateTree->appendDraw(this->writeStream().bytesWritten());
26 fBoundingHierarchy->insert(draw, r, true);
29 void SkBBoxHierarchyRecord::willSave() {
30 fStateTree->appendSave();
31 this->INHERITED::willSave();
34 SkCanvas::SaveLayerStrategy SkBBoxHierarchyRecord::willSaveLayer(const SkRect* bounds,
37 // For now, assume all filters affect transparent black.
38 // FIXME: This could be made less conservative as an optimization.
39 bool paintAffectsTransparentBlack = NULL != paint &&
40 ((NULL != paint->getImageFilter()) ||
41 (NULL != paint->getColorFilter()));
43 if (paintAffectsTransparentBlack) {
46 this->getTotalMatrix().mapRect(&drawBounds);
49 this->getClipDeviceBounds(&deviceBounds);
50 drawBounds.set(deviceBounds);
53 fStateTree->appendSaveLayer(this->writeStream().bytesWritten());
54 SkCanvas::SaveLayerStrategy strategy = this->INHERITED::willSaveLayer(bounds, paint, flags);
55 if (paintAffectsTransparentBlack) {
56 this->handleBBox(drawBounds);
62 void SkBBoxHierarchyRecord::willRestore() {
63 fStateTree->appendRestore();
64 this->INHERITED::willRestore();
67 void SkBBoxHierarchyRecord::didConcat(const SkMatrix& matrix) {
68 fStateTree->appendTransform(getTotalMatrix());
69 INHERITED::didConcat(matrix);
72 void SkBBoxHierarchyRecord::didSetMatrix(const SkMatrix& matrix) {
73 fStateTree->appendTransform(getTotalMatrix());
74 INHERITED::didSetMatrix(matrix);
77 void SkBBoxHierarchyRecord::onClipRect(const SkRect& rect,
79 ClipEdgeStyle edgeStyle) {
80 fStateTree->appendClip(this->writeStream().bytesWritten());
81 this->INHERITED::onClipRect(rect, op, edgeStyle);
84 void SkBBoxHierarchyRecord::onClipRegion(const SkRegion& region,
86 fStateTree->appendClip(this->writeStream().bytesWritten());
87 this->INHERITED::onClipRegion(region, op);
90 void SkBBoxHierarchyRecord::onClipPath(const SkPath& path,
92 ClipEdgeStyle edgeStyle) {
93 fStateTree->appendClip(this->writeStream().bytesWritten());
94 this->INHERITED::onClipPath(path, op, edgeStyle);
97 void SkBBoxHierarchyRecord::onClipRRect(const SkRRect& rrect,
99 ClipEdgeStyle edgeStyle) {
100 fStateTree->appendClip(this->writeStream().bytesWritten());
101 this->INHERITED::onClipRRect(rrect, op, edgeStyle);
104 bool SkBBoxHierarchyRecord::shouldRewind(void* data) {
105 // SkBBoxHierarchy::rewindInserts is called by SkPicture after the
106 // SkPicture has rewound its command stream. To match that rewind in the
107 // BBH, we rewind all draws that reference commands that were recorded
108 // past the point to which the SkPicture has rewound, which is given by
109 // writeStream().bytesWritten().
110 SkPictureStateTree::Draw* draw = static_cast<SkPictureStateTree::Draw*>(data);
111 return draw->fOffset >= writeStream().bytesWritten();