Snapshot.cpp revision ada4d53d50dc869b8278573ad640dc44118d3bcf
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "Snapshot.h" 18 19#include <SkCanvas.h> 20 21namespace android { 22namespace uirenderer { 23 24/////////////////////////////////////////////////////////////////////////////// 25// Constructors 26/////////////////////////////////////////////////////////////////////////////// 27 28Snapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), 29 invisible(false), empty(false) { 30 31 transform = &mTransformRoot; 32 clipRect = &mClipRectRoot; 33 region = NULL; 34} 35 36/** 37 * Copies the specified snapshot/ The specified snapshot is stored as 38 * the previous snapshot. 39 */ 40Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): 41 flags(0), previous(s), layer(NULL), fbo(s->fbo), 42 invisible(s->invisible), empty(false), 43 viewport(s->viewport), height(s->height) { 44 45 if (saveFlags & SkCanvas::kMatrix_SaveFlag) { 46 mTransformRoot.load(*s->transform); 47 transform = &mTransformRoot; 48 } else { 49 transform = s->transform; 50 } 51 52 if (saveFlags & SkCanvas::kClip_SaveFlag) { 53 mClipRectRoot.set(*s->clipRect); 54 clipRect = &mClipRectRoot; 55 } else { 56 clipRect = s->clipRect; 57 } 58 59 if (s->flags & Snapshot::kFlagFboTarget) { 60 flags |= Snapshot::kFlagFboTarget; 61 region = s->region; 62 } else { 63 region = NULL; 64 } 65} 66 67/////////////////////////////////////////////////////////////////////////////// 68// Clipping 69/////////////////////////////////////////////////////////////////////////////// 70 71bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) { 72 Rect r(left, top, right, bottom); 73 transform->mapRect(r); 74 return clipTransformed(r, op); 75} 76 77bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) { 78 bool clipped = false; 79 80 // NOTE: The unimplemented operations require support for regions 81 // Supporting regions would require using a stencil buffer instead 82 // of the scissor. The stencil buffer itself is not too expensive 83 // (memory cost excluded) but on fillrate limited devices, managing 84 // the stencil might have a negative impact on the framerate. 85 switch (op) { 86 case SkRegion::kDifference_Op: 87 break; 88 case SkRegion::kIntersect_Op: 89 clipped = clipRect->intersect(r); 90 if (!clipped) { 91 clipRect->setEmpty(); 92 clipped = true; 93 } 94 break; 95 case SkRegion::kUnion_Op: 96 clipped = clipRect->unionWith(r); 97 break; 98 case SkRegion::kXOR_Op: 99 break; 100 case SkRegion::kReverseDifference_Op: 101 break; 102 case SkRegion::kReplace_Op: 103 clipRect->set(r); 104 clipped = true; 105 break; 106 } 107 108 if (clipped) { 109 flags |= Snapshot::kFlagClipSet; 110 } 111 112 return clipped; 113} 114 115void Snapshot::setClip(float left, float top, float right, float bottom) { 116 clipRect->set(left, top, right, bottom); 117 flags |= Snapshot::kFlagClipSet; 118} 119 120const Rect& Snapshot::getLocalClip() { 121 mat4 inverse; 122 inverse.loadInverse(*transform); 123 124 mLocalClip.set(*clipRect); 125 inverse.mapRect(mLocalClip); 126 127 return mLocalClip; 128} 129 130void Snapshot::resetClip(float left, float top, float right, float bottom) { 131 clipRect = &mClipRectRoot; 132 clipRect->set(left, top, right, bottom); 133 flags |= Snapshot::kFlagClipSet; 134} 135 136/////////////////////////////////////////////////////////////////////////////// 137// Transforms 138/////////////////////////////////////////////////////////////////////////////// 139 140void Snapshot::resetTransform(float x, float y, float z) { 141 transform = &mTransformRoot; 142 transform->loadTranslate(x, y, z); 143} 144 145/////////////////////////////////////////////////////////////////////////////// 146// Queries 147/////////////////////////////////////////////////////////////////////////////// 148 149bool Snapshot::isIgnored() const { 150 return invisible || empty; 151} 152 153}; // namespace uirenderer 154}; // namespace android 155