• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2012 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #include "SkBBoxHierarchyRecord.h"
10 #include "SkPictureStateTree.h"
11 
SkBBoxHierarchyRecord(const SkISize & size,uint32_t recordFlags,SkBBoxHierarchy * h)12 SkBBoxHierarchyRecord::SkBBoxHierarchyRecord(const SkISize& size,
13                                              uint32_t recordFlags,
14                                              SkBBoxHierarchy* h)
15     : INHERITED(size, recordFlags) {
16     fStateTree = SkNEW(SkPictureStateTree);
17     fBoundingHierarchy = h;
18     fBoundingHierarchy->ref();
19     fBoundingHierarchy->setClient(this);
20 }
21 
handleBBox(const SkRect & bounds)22 void SkBBoxHierarchyRecord::handleBBox(const SkRect& bounds) {
23     SkIRect r;
24     bounds.roundOut(&r);
25     SkPictureStateTree::Draw* draw = fStateTree->appendDraw(this->writeStream().bytesWritten());
26     fBoundingHierarchy->insert(draw, r, true);
27 }
28 
willSave(SaveFlags flags)29 void SkBBoxHierarchyRecord::willSave(SaveFlags flags) {
30     fStateTree->appendSave();
31     this->INHERITED::willSave(flags);
32 }
33 
willSaveLayer(const SkRect * bounds,const SkPaint * paint,SaveFlags flags)34 SkCanvas::SaveLayerStrategy SkBBoxHierarchyRecord::willSaveLayer(const SkRect* bounds,
35                                                                  const SkPaint* paint,
36                                                                  SaveFlags flags) {
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()));
42     SkRect drawBounds;
43     if (paintAffectsTransparentBlack) {
44         if (bounds) {
45             drawBounds = *bounds;
46             this->getTotalMatrix().mapRect(&drawBounds);
47         } else {
48             SkIRect deviceBounds;
49             this->getClipDeviceBounds(&deviceBounds);
50             drawBounds.set(deviceBounds);
51         }
52     }
53     fStateTree->appendSaveLayer(this->writeStream().bytesWritten());
54     SkCanvas::SaveLayerStrategy strategy = this->INHERITED::willSaveLayer(bounds, paint, flags);
55     if (paintAffectsTransparentBlack) {
56         this->handleBBox(drawBounds);
57         this->addNoOp();
58     }
59     return strategy;
60 }
61 
willRestore()62 void SkBBoxHierarchyRecord::willRestore() {
63     fStateTree->appendRestore();
64     this->INHERITED::willRestore();
65 }
66 
didConcat(const SkMatrix & matrix)67 void SkBBoxHierarchyRecord::didConcat(const SkMatrix& matrix) {
68     fStateTree->appendTransform(getTotalMatrix());
69     INHERITED::didConcat(matrix);
70 }
71 
didSetMatrix(const SkMatrix & matrix)72 void SkBBoxHierarchyRecord::didSetMatrix(const SkMatrix& matrix) {
73     fStateTree->appendTransform(getTotalMatrix());
74     INHERITED::didSetMatrix(matrix);
75 }
76 
onClipRect(const SkRect & rect,SkRegion::Op op,ClipEdgeStyle edgeStyle)77 void SkBBoxHierarchyRecord::onClipRect(const SkRect& rect,
78                                        SkRegion::Op op,
79                                        ClipEdgeStyle edgeStyle) {
80     fStateTree->appendClip(this->writeStream().bytesWritten());
81     this->INHERITED::onClipRect(rect, op, edgeStyle);
82 }
83 
onClipRegion(const SkRegion & region,SkRegion::Op op)84 void SkBBoxHierarchyRecord::onClipRegion(const SkRegion& region,
85                                          SkRegion::Op op) {
86     fStateTree->appendClip(this->writeStream().bytesWritten());
87     this->INHERITED::onClipRegion(region, op);
88 }
89 
onClipPath(const SkPath & path,SkRegion::Op op,ClipEdgeStyle edgeStyle)90 void SkBBoxHierarchyRecord::onClipPath(const SkPath& path,
91                                        SkRegion::Op op,
92                                        ClipEdgeStyle edgeStyle) {
93     fStateTree->appendClip(this->writeStream().bytesWritten());
94     this->INHERITED::onClipPath(path, op, edgeStyle);
95 }
96 
onClipRRect(const SkRRect & rrect,SkRegion::Op op,ClipEdgeStyle edgeStyle)97 void SkBBoxHierarchyRecord::onClipRRect(const SkRRect& rrect,
98                                         SkRegion::Op op,
99                                         ClipEdgeStyle edgeStyle) {
100     fStateTree->appendClip(this->writeStream().bytesWritten());
101     this->INHERITED::onClipRRect(rrect, op, edgeStyle);
102 }
103 
shouldRewind(void * data)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();
112 }
113