gfx/skia/trunk/src/core/SkPictureStateTree.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2012 Google Inc.
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9 #include "SkPictureStateTree.h"
michael@0 10 #include "SkCanvas.h"
michael@0 11
michael@0 12 SkPictureStateTree::SkPictureStateTree()
michael@0 13 : fAlloc(2048)
michael@0 14 , fLastRestoredNode(NULL)
michael@0 15 , fStateStack(sizeof(Draw), 16) {
michael@0 16 fRootMatrix.reset();
michael@0 17 fRoot.fParent = NULL;
michael@0 18 fRoot.fMatrix = &fRootMatrix;
michael@0 19 fRoot.fFlags = Node::kSave_Flag;
michael@0 20 fRoot.fOffset = 0;
michael@0 21 fRoot.fLevel = 0;
michael@0 22 fCurrentState.fNode = &fRoot;
michael@0 23 fCurrentState.fMatrix = &fRootMatrix;
michael@0 24 *static_cast<Draw*>(fStateStack.push_back()) = fCurrentState;
michael@0 25 }
michael@0 26
michael@0 27 SkPictureStateTree::~SkPictureStateTree() {
michael@0 28 }
michael@0 29
michael@0 30 SkPictureStateTree::Draw* SkPictureStateTree::appendDraw(size_t offset) {
michael@0 31 Draw* draw = static_cast<Draw*>(fAlloc.allocThrow(sizeof(Draw)));
michael@0 32 *draw = fCurrentState;
michael@0 33 draw->fOffset = SkToU32(offset);
michael@0 34 return draw;
michael@0 35 }
michael@0 36
michael@0 37 void SkPictureStateTree::appendSave() {
michael@0 38 *static_cast<Draw*>(fStateStack.push_back()) = fCurrentState;
michael@0 39 fCurrentState.fNode->fFlags |= Node::kSave_Flag;
michael@0 40 }
michael@0 41
michael@0 42 void SkPictureStateTree::appendSaveLayer(size_t offset) {
michael@0 43 *static_cast<Draw*>(fStateStack.push_back()) = fCurrentState;
michael@0 44 this->appendNode(offset);
michael@0 45 fCurrentState.fNode->fFlags |= Node::kSaveLayer_Flag;
michael@0 46 }
michael@0 47
michael@0 48 void SkPictureStateTree::saveCollapsed() {
michael@0 49 SkASSERT(NULL != fLastRestoredNode);
michael@0 50 SkASSERT(SkToBool(fLastRestoredNode->fFlags & \
michael@0 51 (Node::kSaveLayer_Flag | Node::kSave_Flag)));
michael@0 52 SkASSERT(fLastRestoredNode->fParent == fCurrentState.fNode);
michael@0 53 // The structure of the tree is not modified here. We just turn off
michael@0 54 // the save or saveLayer flag to prevent the iterator from making state
michael@0 55 // changing calls on the playback canvas when traversing a save or
michael@0 56 // saveLayerNode node.
michael@0 57 fLastRestoredNode->fFlags = 0;
michael@0 58 }
michael@0 59
michael@0 60 void SkPictureStateTree::appendRestore() {
michael@0 61 fLastRestoredNode = fCurrentState.fNode;
michael@0 62 fCurrentState = *static_cast<Draw*>(fStateStack.back());
michael@0 63 fStateStack.pop_back();
michael@0 64 }
michael@0 65
michael@0 66 void SkPictureStateTree::appendTransform(const SkMatrix& trans) {
michael@0 67 SkMatrix* m = static_cast<SkMatrix*>(fAlloc.allocThrow(sizeof(SkMatrix)));
michael@0 68 *m = trans;
michael@0 69 fCurrentState.fMatrix = m;
michael@0 70 }
michael@0 71
michael@0 72 void SkPictureStateTree::appendClip(size_t offset) {
michael@0 73 this->appendNode(offset);
michael@0 74 }
michael@0 75
michael@0 76 SkPictureStateTree::Iterator SkPictureStateTree::getIterator(const SkTDArray<void*>& draws,
michael@0 77 SkCanvas* canvas) {
michael@0 78 return Iterator(draws, canvas, &fRoot);
michael@0 79 }
michael@0 80
michael@0 81 void SkPictureStateTree::appendNode(size_t offset) {
michael@0 82 Node* n = static_cast<Node*>(fAlloc.allocThrow(sizeof(Node)));
michael@0 83 n->fOffset = SkToU32(offset);
michael@0 84 n->fFlags = 0;
michael@0 85 n->fParent = fCurrentState.fNode;
michael@0 86 n->fLevel = fCurrentState.fNode->fLevel + 1;
michael@0 87 n->fMatrix = fCurrentState.fMatrix;
michael@0 88 fCurrentState.fNode = n;
michael@0 89 }
michael@0 90
michael@0 91 SkPictureStateTree::Iterator::Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root)
michael@0 92 : fDraws(&draws)
michael@0 93 , fCanvas(canvas)
michael@0 94 , fCurrentNode(root)
michael@0 95 , fPlaybackMatrix(canvas->getTotalMatrix())
michael@0 96 , fCurrentMatrix(NULL)
michael@0 97 , fPlaybackIndex(0)
michael@0 98 , fSave(false)
michael@0 99 , fValid(true) {
michael@0 100 }
michael@0 101
michael@0 102 uint32_t SkPictureStateTree::Iterator::draw() {
michael@0 103 SkASSERT(this->isValid());
michael@0 104 if (fPlaybackIndex >= fDraws->count()) {
michael@0 105 // restore back to where we started
michael@0 106 fCanvas->setMatrix(fPlaybackMatrix);
michael@0 107 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { fCanvas->restore(); }
michael@0 108 fCurrentNode = fCurrentNode->fParent;
michael@0 109 while (NULL != fCurrentNode) {
michael@0 110 if (fCurrentNode->fFlags & Node::kSave_Flag) { fCanvas->restore(); }
michael@0 111 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { fCanvas->restore(); }
michael@0 112 fCurrentNode = fCurrentNode->fParent;
michael@0 113 }
michael@0 114 return kDrawComplete;
michael@0 115 }
michael@0 116
michael@0 117 Draw* draw = static_cast<Draw*>((*fDraws)[fPlaybackIndex]);
michael@0 118 Node* targetNode = draw->fNode;
michael@0 119
michael@0 120 if (fSave) {
michael@0 121 fCanvas->save(SkCanvas::kClip_SaveFlag);
michael@0 122 fSave = false;
michael@0 123 }
michael@0 124
michael@0 125 if (fCurrentNode != targetNode) {
michael@0 126 // If we're not at the target and we don't have a list of nodes to get there, we need to
michael@0 127 // figure out the path from our current node, to the target
michael@0 128 if (fNodes.count() == 0) {
michael@0 129 // Trace back up to a common ancestor, restoring to get our current state to match that
michael@0 130 // of the ancestor, and saving a list of nodes whose state we need to apply to get to
michael@0 131 // the target (we can restore up to the ancestor immediately, but we'll need to return
michael@0 132 // an offset for each node on the way down to the target, to apply the desired clips and
michael@0 133 // saveLayers, so it may take several draw() calls before the next draw actually occurs)
michael@0 134 Node* tmp = fCurrentNode;
michael@0 135 Node* ancestor = targetNode;
michael@0 136 while (tmp != ancestor) {
michael@0 137 uint16_t currentLevel = tmp->fLevel;
michael@0 138 uint16_t targetLevel = ancestor->fLevel;
michael@0 139 if (currentLevel >= targetLevel) {
michael@0 140 if (tmp != fCurrentNode && tmp->fFlags & Node::kSave_Flag) { fCanvas->restore(); }
michael@0 141 if (tmp->fFlags & Node::kSaveLayer_Flag) { fCanvas->restore(); }
michael@0 142 tmp = tmp->fParent;
michael@0 143 }
michael@0 144 if (currentLevel <= targetLevel) {
michael@0 145 fNodes.push(ancestor);
michael@0 146 ancestor = ancestor->fParent;
michael@0 147 }
michael@0 148 }
michael@0 149
michael@0 150 if (ancestor->fFlags & Node::kSave_Flag) {
michael@0 151 if (fCurrentNode != ancestor) { fCanvas->restore(); }
michael@0 152 if (targetNode != ancestor) { fCanvas->save(SkCanvas::kClip_SaveFlag); }
michael@0 153 }
michael@0 154 fCurrentNode = ancestor;
michael@0 155 }
michael@0 156
michael@0 157 // If we're not at the target node yet, we'll need to return an offset to make the caller
michael@0 158 // apply the next clip or saveLayer.
michael@0 159 if (fCurrentNode != targetNode) {
michael@0 160 if (fCurrentMatrix != fNodes.top()->fMatrix) {
michael@0 161 fCurrentMatrix = fNodes.top()->fMatrix;
michael@0 162 SkMatrix tmp = *fNodes.top()->fMatrix;
michael@0 163 tmp.postConcat(fPlaybackMatrix);
michael@0 164 fCanvas->setMatrix(tmp);
michael@0 165 }
michael@0 166 uint32_t offset = fNodes.top()->fOffset;
michael@0 167 fCurrentNode = fNodes.top();
michael@0 168 fSave = fCurrentNode != targetNode && fCurrentNode->fFlags & Node::kSave_Flag;
michael@0 169 fNodes.pop();
michael@0 170 return offset;
michael@0 171 }
michael@0 172 }
michael@0 173
michael@0 174 // If we got this far, the clip/saveLayer state is all set, so we can proceed to set the matrix
michael@0 175 // for the draw, and return its offset.
michael@0 176
michael@0 177 if (fCurrentMatrix != draw->fMatrix) {
michael@0 178 SkMatrix tmp = *draw->fMatrix;
michael@0 179 tmp.postConcat(fPlaybackMatrix);
michael@0 180 fCanvas->setMatrix(tmp);
michael@0 181 fCurrentMatrix = draw->fMatrix;
michael@0 182 }
michael@0 183
michael@0 184 ++fPlaybackIndex;
michael@0 185 return draw->fOffset;
michael@0 186 }

mercurial