CanvasState.cpp revision d41c4d8c732095ae99c955b6b82f7306633004b1
114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/* 214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Copyright (C) 2014 The Android Open Source Project 314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * you may not use this file except in compliance with the License. 614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * You may obtain a copy of the License at 714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * http://www.apache.org/licenses/LICENSE-2.0 914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 1014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Unless required by applicable law or agreed to in writing, software 1114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * distributed under the License is distributed on an "AS IS" BASIS, 1214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See the License for the specific language governing permissions and 1414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * limitations under the License. 1514e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 1614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 1714e513058ed4168c94e015638d16f5f87fd8063aChris Craik#include <SkCanvas.h> 1814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 19984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include "CanvasState.h" 20af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik#include "utils/MathUtils.h" 21af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 2214e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace android { 2314e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace uirenderer { 2414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 25984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 26984162fb7e4010b6e2908352dbff17ed47eecf06Tom HudsonCanvasState::CanvasState(CanvasStateClient& renderer) 27058fc640017c90120c599d378a4cbc55668b05b7Chris Craik : mDirtyClip(false) 28058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mWidth(-1) 29058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mHeight(-1) 30058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mSaveCount(1) 31058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mFirstSnapshot(new Snapshot) 32984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson , mCanvas(renderer) 33058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mSnapshot(mFirstSnapshot) { 34984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 3514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 3614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 37984162fb7e4010b6e2908352dbff17ed47eecf06Tom HudsonCanvasState::~CanvasState() { 38984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 39984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} 40984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 41984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::initializeSaveStack(float clipLeft, float clipTop, 4269e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik float clipRight, float clipBottom, const Vector3& lightCenter) { 4314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mFirstSnapshot, 4414e513058ed4168c94e015638d16f5f87fd8063aChris Craik SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 4514e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom); 46984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mSnapshot->fbo = mCanvas.onGetTargetFbo(); 4769e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik mSnapshot->setRelativeLightCenter(lightCenter); 4814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount = 1; 4914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 5014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 51984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setViewport(int width, int height) { 5214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mWidth = width; 5314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mHeight = height; 54a64a2bef1048db5a742843f1e3bea9e80d0defc5Chris Craik mFirstSnapshot->initializeViewport(width, height); 55984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mCanvas.onViewportInitialized(); 56284b24358410cb0200e525a5ba36994090c83f20Chris Craik 57284b24358410cb0200e525a5ba36994090c83f20Chris Craik // create a temporary 1st snapshot, so old snapshots are released, 58284b24358410cb0200e525a5ba36994090c83f20Chris Craik // and viewport can be queried safely. 59284b24358410cb0200e525a5ba36994090c83f20Chris Craik // TODO: remove, combine viewport + save stack initialization 60284b24358410cb0200e525a5ba36994090c83f20Chris Craik mSnapshot = new Snapshot(mFirstSnapshot, 61284b24358410cb0200e525a5ba36994090c83f20Chris Craik SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 62284b24358410cb0200e525a5ba36994090c83f20Chris Craik mSaveCount = 1; 63797b95b26bbb7557678af78b9a2a61830158920fChris Craik} 64797b95b26bbb7557678af78b9a2a61830158920fChris Craik 6514e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 6614e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Save (layer) 6714e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 6814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 6914e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 70984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to save without side-effects 7114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 72984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save 7314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * stack, and ensures restoreToCount() doesn't call back into subclass overrides. 7414e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 75984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::saveSnapshot(int flags) { 7614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mSnapshot, flags); 7714e513058ed4168c94e015638d16f5f87fd8063aChris Craik return mSaveCount++; 7814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 7914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 80984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::save(int flags) { 8114e513058ed4168c94e015638d16f5f87fd8063aChris Craik return saveSnapshot(flags); 8214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 8314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 85984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to restore without side-effects. 8614e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 87984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreSnapshot() { 8814e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRemove = mSnapshot; 8914e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRestore = mSnapshot->previous; 9014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount--; 9214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = toRestore; 9314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9414e513058ed4168c94e015638d16f5f87fd8063aChris Craik // subclass handles restore implementation 95984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mCanvas.onSnapshotRestored(*toRemove, *toRestore); 9614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 9714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 98984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restore() { 9914e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSaveCount > 1) { 10014e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 10114e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 10214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 10314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 104984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreToCount(int saveCount) { 10514e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (saveCount < 1) saveCount = 1; 10614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10714e513058ed4168c94e015638d16f5f87fd8063aChris Craik while (mSaveCount > saveCount) { 10814e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 10914e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 11014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 11214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 11314e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Matrix 11414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 11514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 116984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::getMatrix(SkMatrix* matrix) const { 11714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->copyTo(*matrix); 11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 120984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::translate(float dx, float dy, float dz) { 12114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->translate(dx, dy, dz); 12214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 124984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::rotate(float degrees) { 12514e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); 12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 128984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::scale(float sx, float sy) { 12914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->scale(sx, sy, 1.0f); 13014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 132984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::skew(float sx, float sy) { 13314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->skew(sx, sy); 13414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 136984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const SkMatrix& matrix) { 137139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mSnapshot->transform->load(matrix); 13814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 140984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const Matrix4& matrix) { 14114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->load(matrix); 14214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 144984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const SkMatrix& matrix) { 145139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mat4 transform(matrix); 14614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(transform); 14714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 149984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const Matrix4& matrix) { 15014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(matrix); 15114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 15214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 15314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 15414e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Clip 15514e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 15614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 157984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 158d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (CC_LIKELY(currentTransform()->rectToRect())) { 159d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op); 160d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 161d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 162d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 163d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkPath path; 164d6b65f67717025b1162f86f04e2caa5723566cacChris Craik path.addRect(left, top, right, bottom); 165d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 166984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson return CanvasState::clipPath(&path, op); 167d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 168d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 169984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) { 170d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkMatrix transform; 171d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->copyTo(transform); 172d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 173d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkPath transformed; 174d6b65f67717025b1162f86f04e2caa5723566cacChris Craik path->transform(transform, &transformed); 175d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 176d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkRegion clip; 177d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (!mSnapshot->previous->clipRegion->isEmpty()) { 178d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRegion(*mSnapshot->previous->clipRegion); 179d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } else { 180d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (mSnapshot->previous == firstSnapshot()) { 181d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRect(0, 0, getWidth(), getHeight()); 182d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } else { 183d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect* bounds = mSnapshot->previous->clipRect; 184d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom); 185d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 186d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 187d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 188d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkRegion region; 189d6b65f67717025b1162f86f04e2caa5723566cacChris Craik region.setPath(transformed, clip); 190d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 19162d307c2402777d5e53b4590af5f32f8c55afd81Chris Craik // region is the transformed input path, masked by the previous clip 192d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clipRegionTransformed(region, op); 193d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 194d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 195d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 196984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) { 197d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op); 198d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 199d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 20014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 201984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { 202af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik Rect bounds; 203af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik float radius; 204af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported 205af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 20679d26c72aa6f898125df2386054f6a293da4122aChris Craik bool outlineIsRounded = MathUtils::isPositive(radius); 20779d26c72aa6f898125df2386054f6a293da4122aChris Craik if (!outlineIsRounded || currentTransform()->isSimple()) { 208af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik // TODO: consider storing this rect separately, so that this can't be replaced with clip ops 209af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op); 210af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik } 21179d26c72aa6f898125df2386054f6a293da4122aChris Craik if (outlineIsRounded) { 212e83cbd451868a734bfac07ccd680d5617080b579Chris Craik setClippingRoundRect(allocator, bounds, radius, false); 21379d26c72aa6f898125df2386054f6a293da4122aChris Craik } 214deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik} 215deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 216984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingRoundRect(LinearAllocator& allocator, 217e83cbd451868a734bfac07ccd680d5617080b579Chris Craik const Rect& rect, float radius, bool highPriority) { 218e83cbd451868a734bfac07ccd680d5617080b579Chris Craik mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); 219af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik} 220af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 221af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 22214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 22314e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Quick Rejection 22414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 22514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 22614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 22714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Calculates whether content drawn within the passed bounds would be outside of, or intersect with 22814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * the clipRect. Does not modify the scissor. 22914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 23014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param clipRequired if not null, will be set to true if element intersects clip 23114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * (and wasn't rejected) 23214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 23314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param snapOut if set, the geometry will be treated as having an AA ramp. 23414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See Rect::snapGeometryToPixelBoundaries() 23514e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 236984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::calculateQuickRejectForScissor(float left, float top, 237deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik float right, float bottom, 238deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool* clipRequired, bool* roundRectClipRequired, 239deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool snapOut) const { 24014e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 24114e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 24214e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 24314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24414e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 245d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 24614e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.snapGeometryToPixelBoundaries(snapOut); 24714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 248d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect clipRect(*currentClipRect()); 24914e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 25014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 25114e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 25214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 25314e513058ed4168c94e015638d16f5f87fd8063aChris Craik // clip is required if geometry intersects clip rect 254deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (clipRequired) { 255deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik *clipRequired = !clipRect.contains(r); 256deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 257deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 258deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // round rect clip is required if RR clip exists, and geometry intersects its corners 259deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (roundRectClipRequired) { 260d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik *roundRectClipRequired = mSnapshot->roundRectClipState != nullptr 261deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik && mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r); 262deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 26314e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 26414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 26514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 266984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::quickRejectConservative(float left, float top, 26714e513058ed4168c94e015638d16f5f87fd8063aChris Craik float right, float bottom) const { 26814e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 26914e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 27014e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 27114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 27214e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 273d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 27414e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.roundOut(); // rounded out to be conservative 27514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 276d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect clipRect(*currentClipRect()); 27714e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 27814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 27914e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 28014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 28114e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 28214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 28314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 284984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace uirenderer 285984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace android 286