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 175f803623559aab395a29d575c37c4e39c23a4b4eChris Craik#define LOG_TAG "OpenGLRenderer" 185f803623559aab395a29d575c37c4e39c23a4b4eChris Craik 19ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include "Snapshot.h" 20ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 21ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include <SkCanvas.h> 22ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 23ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace android { 24ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace uirenderer { 25ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 26ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 27ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Constructors 28ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 29ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 30ada4d53d50dc869b8278573ad640dc44118d3bcfRomain GuySnapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), 31db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase invisible(false), empty(false), alpha(1.0f) { 32ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 33ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = &mTransformRoot; 34ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect = &mClipRectRoot; 35ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy region = NULL; 368ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy clipRegion = &mClipRegionRoot; 37ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 38ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 39ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/** 40ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Copies the specified snapshot/ The specified snapshot is stored as 41ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * the previous snapshot. 42ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy */ 43ada4d53d50dc869b8278573ad640dc44118d3bcfRomain GuySnapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): 448ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy flags(0), previous(s), layer(s->layer), fbo(s->fbo), 45ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy invisible(s->invisible), empty(false), 46db8c9a6a4d9bf8c39f834b25611926caf21380f6Chet Haase viewport(s->viewport), height(s->height), alpha(s->alpha) { 47ada4d53d50dc869b8278573ad640dc44118d3bcfRomain 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; 588ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy if (!s->clipRegion->isEmpty()) { 590baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy mClipRegionRoot.op(*s->clipRegion, SkRegion::kUnion_Op); 60967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 618ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy clipRegion = &mClipRegionRoot; 62ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } else { 63ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect = s->clipRect; 64967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRegion = s->clipRegion; 65ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 66ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 67ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy if (s->flags & Snapshot::kFlagFboTarget) { 68ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags |= Snapshot::kFlagFboTarget; 69ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy region = s->region; 70ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } else { 71ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy region = NULL; 72ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 73ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 74ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 75ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 76ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Clipping 77ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 78ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 79967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guyvoid Snapshot::ensureClipRegion() { 808ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy if (clipRegion->isEmpty()) { 810baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRegion->setRect(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); 82967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 83967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy} 84967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 85967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guyvoid Snapshot::copyClipRectFromRegion() { 86967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (!clipRegion->isEmpty()) { 870baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy const SkIRect& bounds = clipRegion->getBounds(); 880baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRect->set(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); 89967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 90967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (clipRegion->isRect()) { 910baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRegion->setEmpty(); 92967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 93967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } else { 94967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRect->setEmpty(); 95967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 96967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy} 97967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 980baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guybool Snapshot::clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op) { 990baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy SkIRect tmp; 1000baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy tmp.set(left, top, right, bottom); 1010baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRegion->op(tmp, op); 102967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy copyClipRectFromRegion(); 103967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy return true; 1048ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy} 1058ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy 1068ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guybool Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) { 1078ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy ensureClipRegion(); 1088ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy clipRegion->op(region, op); 1098ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy copyClipRectFromRegion(); 1108ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy flags |= Snapshot::kFlagClipSet; 1118ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy return true; 112967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy} 113967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 114ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) { 115ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy Rect r(left, top, right, bottom); 116ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform->mapRect(r); 117ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return clipTransformed(r, op); 118ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 119ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 120ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) { 121ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy bool clipped = false; 122ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 123ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy switch (op) { 124967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy case SkRegion::kIntersect_Op: { 1258ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy if (CC_UNLIKELY(!clipRegion->isEmpty())) { 126735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy ensureClipRegion(); 1270baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kIntersect_Op); 128967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } else { 129967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipped = clipRect->intersect(r); 130967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy if (!clipped) { 131967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipRect->setEmpty(); 132967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy clipped = true; 133967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 134ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 135ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy break; 136967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 137967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy case SkRegion::kReplace_Op: { 138967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy setClip(r.left, r.top, r.right, r.bottom); 139ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipped = true; 140ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy break; 141967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 1420baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy default: { 1430baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy ensureClipRegion(); 1440baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, op); 1450baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy break; 1460baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy } 147ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 148ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 149ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy if (clipped) { 150ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags |= Snapshot::kFlagClipSet; 151ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 152ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 153ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return clipped; 154ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 155ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 156ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::setClip(float left, float top, float right, float bottom) { 157ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect->set(left, top, right, bottom); 1588ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy if (!clipRegion->isEmpty()) { 1590baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy clipRegion->setEmpty(); 160967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy } 161ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags |= Snapshot::kFlagClipSet; 162ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 163ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 164a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guybool Snapshot::hasPerspectiveTransform() const { 165a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy return transform->isPerspective(); 166a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy} 167a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy 168ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyconst Rect& Snapshot::getLocalClip() { 169ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy mat4 inverse; 170ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy inverse.loadInverse(*transform); 171ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 172ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy mLocalClip.set(*clipRect); 173ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy inverse.mapRect(mLocalClip); 174ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 175ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return mLocalClip; 176ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 177ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 178ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetClip(float left, float top, float right, float bottom) { 1793bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy // TODO: This is incorrect, when we start rendering into a new layer, 1803bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy // we may have to modify the previous snapshot's clip rect and clip 1813bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy // region if the previous restore() call did not restore the clip 182ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy clipRect = &mClipRectRoot; 1833c099c42fd7ead1429076055990ae39b72c904f4Romain Guy clipRegion = &mClipRegionRoot; 184967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy setClip(left, top, right, bottom); 185ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 186ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 187ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 188ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Transforms 189ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 190ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 191ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetTransform(float x, float y, float z) { 192ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = &mTransformRoot; 193ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform->loadTranslate(x, y, z); 194ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 195ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 196ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 197ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Queries 198ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 199ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 200ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::isIgnored() const { 201ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return invisible || empty; 202ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 203ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 2045f803623559aab395a29d575c37c4e39c23a4b4eChris Craikvoid Snapshot::dump() const { 2055f803623559aab395a29d575c37c4e39c23a4b4eChris Craik ALOGD("Snapshot %p, flags %x, prev %p, height %d, ignored %d, hasComplexClip %d", 2065f803623559aab395a29d575c37c4e39c23a4b4eChris Craik this, flags, previous.get(), height, isIgnored(), clipRegion && !clipRegion->isEmpty()); 2075f803623559aab395a29d575c37c4e39c23a4b4eChris Craik ALOGD(" ClipRect (at %p) %.1f %.1f %.1f %.1f", 2085f803623559aab395a29d575c37c4e39c23a4b4eChris Craik clipRect, clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); 2095f803623559aab395a29d575c37c4e39c23a4b4eChris Craik ALOGD(" Transform (at %p):", transform); 2105f803623559aab395a29d575c37c4e39c23a4b4eChris Craik transform->dump(); 2115f803623559aab395a29d575c37c4e39c23a4b4eChris Craik} 2125f803623559aab395a29d575c37c4e39c23a4b4eChris Craik 213ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace uirenderer 214ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace android 215