1ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/* 2ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Copyright (C) 2012 The Android Open Source Project 3ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * 4ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * you may not use this file except in compliance with the License. 6ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * You may obtain a copy of the License at 7ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * 8ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 9ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * 10ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Unless required by applicable law or agreed to in writing, software 11ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * See the License for the specific language governing permissions and 14ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * limitations under the License. 15ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy */ 16ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 17ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include "Snapshot.h" 18ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 19ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include <SkCanvas.h> 20ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 21ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace android { 22ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace uirenderer { 23ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 24ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 25ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Constructors 26ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 27ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 28ada4d53d50dc869b8278573ad640dc44118d3bcfRomain GuySnapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), 29db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase invisible(false), empty(false), alpha(1.0f) { 30ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 31ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = &mTransformRoot; 32ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect = &mClipRectRoot; 33ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy region = NULL; 34967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRegion = NULL; 35ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 36ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 37ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/** 38ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Copies the specified snapshot/ The specified snapshot is stored as 39ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * the previous snapshot. 40ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy */ 41ada4d53d50dc869b8278573ad640dc44118d3bcfRomain GuySnapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): 42ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags(0), previous(s), layer(NULL), fbo(s->fbo), 43ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy invisible(s->invisible), empty(false), 44db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase viewport(s->viewport), height(s->height), alpha(s->alpha) { 45ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 4621c9c8551d9ab36629cabc01f228d3a302e0c673Romain Guy clipRegion = NULL; 4721c9c8551d9ab36629cabc01f228d3a302e0c673Romain Guy 48ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy if (saveFlags & SkCanvas::kMatrix_SaveFlag) { 49ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy mTransformRoot.load(*s->transform); 50ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = &mTransformRoot; 51ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } else { 52ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = s->transform; 53ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 54ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 55ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy if (saveFlags & SkCanvas::kClip_SaveFlag) { 56ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy mClipRectRoot.set(*s->clipRect); 57ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect = &mClipRectRoot; 58967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE 59967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (s->clipRegion) { 600baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy mClipRegionRoot.op(*s->clipRegion, SkRegion::kUnion_Op); 61967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRegion = &mClipRegionRoot; 62967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 63967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif 64ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } else { 65ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect = s->clipRect; 66967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE 67967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRegion = s->clipRegion; 68967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif 69ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 70ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 71ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy if (s->flags & Snapshot::kFlagFboTarget) { 72ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags |= Snapshot::kFlagFboTarget; 73ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy region = s->region; 74ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } else { 75ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy region = NULL; 76ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 77ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 78ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 79ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 80ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Clipping 81ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 82ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 83967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guyvoid Snapshot::ensureClipRegion() { 84967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE 85967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (!clipRegion) { 86967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRegion = &mClipRegionRoot; 870baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRegion->setRect(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); 88967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 89967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif 90967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy} 91967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 92967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guyvoid Snapshot::copyClipRectFromRegion() { 93967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE 94967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (!clipRegion->isEmpty()) { 950baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy const SkIRect& bounds = clipRegion->getBounds(); 960baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRect->set(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); 97967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 98967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (clipRegion->isRect()) { 990baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRegion->setEmpty(); 100967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRegion = NULL; 101967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 102967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } else { 103967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRect->setEmpty(); 104967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRegion = NULL; 105967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 106967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif 107967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy} 108967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 1090baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guybool Snapshot::clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op) { 110967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#if STENCIL_BUFFER_SIZE 1110baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy SkIRect tmp; 1120baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy tmp.set(left, top, right, bottom); 1130baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRegion->op(tmp, op); 114967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy copyClipRectFromRegion(); 115967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy return true; 116967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#else 117967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy return false; 118967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy#endif 119967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy} 120967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 121ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) { 122ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy Rect r(left, top, right, bottom); 123ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform->mapRect(r); 124ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return clipTransformed(r, op); 125ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 126ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 127ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) { 128ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy bool clipped = false; 129ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 130ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy switch (op) { 131967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy case SkRegion::kIntersect_Op: { 132967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (CC_UNLIKELY(clipRegion)) { 1330baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kIntersect_Op); 134967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } else { 135967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipped = clipRect->intersect(r); 136967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (!clipped) { 137967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRect->setEmpty(); 138967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipped = true; 139967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 140ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 141ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy break; 142967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 143967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy case SkRegion::kUnion_Op: { 144967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (CC_UNLIKELY(clipRegion)) { 1450baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kUnion_Op); 146967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } else { 147967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipped = clipRect->unionWith(r); 148967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 149ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy break; 150967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 151967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy case SkRegion::kReplace_Op: { 152967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy setClip(r.left, r.top, r.right, r.bottom); 153ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipped = true; 154ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy break; 155967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 1560baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy default: { 1570baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy ensureClipRegion(); 1580baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, op); 1590baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy break; 1600baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy } 161ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 162ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 163ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy if (clipped) { 164ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags |= Snapshot::kFlagClipSet; 165ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 166ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 167ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return clipped; 168ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 169ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 170ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::setClip(float left, float top, float right, float bottom) { 171ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect->set(left, top, right, bottom); 17221c9c8551d9ab36629cabc01f228d3a302e0c673Romain Guy#if STENCIL_BUFFER_SIZE 173967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (clipRegion) { 1740baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRegion->setEmpty(); 175967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRegion = NULL; 176967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 17721c9c8551d9ab36629cabc01f228d3a302e0c673Romain Guy#endif 178ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags |= Snapshot::kFlagClipSet; 179ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 180ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 181a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guybool Snapshot::hasPerspectiveTransform() const { 182a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy return transform->isPerspective(); 183a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy} 184a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy 185ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyconst Rect& Snapshot::getLocalClip() { 186ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy mat4 inverse; 187ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy inverse.loadInverse(*transform); 188ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 189ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy mLocalClip.set(*clipRect); 190ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy inverse.mapRect(mLocalClip); 191ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 192ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return mLocalClip; 193ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 194ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 195ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetClip(float left, float top, float right, float bottom) { 196ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect = &mClipRectRoot; 197967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy setClip(left, top, right, bottom); 198ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 199ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 200ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 201ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Transforms 202ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 203ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 204ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetTransform(float x, float y, float z) { 205ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = &mTransformRoot; 206ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform->loadTranslate(x, y, z); 207ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 208ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 209ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 210ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Queries 211ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 212ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 213ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::isIgnored() const { 214ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return invisible || empty; 215ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 216ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 217ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace uirenderer 218ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace android 219