Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkBBoxHierarchyRecord.cpp
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
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
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
29 void SkBBoxHierarchyRecord::willSave() {
30     fStateTree->appendSave();
31     this->INHERITED::willSave();
32 }
33
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
62 void SkBBoxHierarchyRecord::willRestore() {
63     fStateTree->appendRestore();
64     this->INHERITED::willRestore();
65 }
66
67 void SkBBoxHierarchyRecord::didConcat(const SkMatrix& matrix) {
68     fStateTree->appendTransform(getTotalMatrix());
69     INHERITED::didConcat(matrix);
70 }
71
72 void SkBBoxHierarchyRecord::didSetMatrix(const SkMatrix& matrix) {
73     fStateTree->appendTransform(getTotalMatrix());
74     INHERITED::didSetMatrix(matrix);
75 }
76
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
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
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
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
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 }