CanvasState.cpp revision d9ee550888011a64fa3f35e666360ec8278597d8
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) 31984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson , mCanvas(renderer) 32d9ee550888011a64fa3f35e666360ec8278597d8John Reck , mSnapshot(&mFirstSnapshot) { 33d9ee550888011a64fa3f35e666360ec8278597d8John Reck} 34d9ee550888011a64fa3f35e666360ec8278597d8John Reck 35d9ee550888011a64fa3f35e666360ec8278597d8John ReckCanvasState::~CanvasState() { 36d9ee550888011a64fa3f35e666360ec8278597d8John Reck // First call freeSnapshot on all but mFirstSnapshot 37d9ee550888011a64fa3f35e666360ec8278597d8John Reck // to invoke all the dtors 38d9ee550888011a64fa3f35e666360ec8278597d8John Reck freeAllSnapshots(); 39984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 40d9ee550888011a64fa3f35e666360ec8278597d8John Reck // Now actually release the memory 41d9ee550888011a64fa3f35e666360ec8278597d8John Reck while (mSnapshotPool) { 42d9ee550888011a64fa3f35e666360ec8278597d8John Reck void* temp = mSnapshotPool; 43d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPool = mSnapshotPool->previous; 44d9ee550888011a64fa3f35e666360ec8278597d8John Reck free(temp); 45d9ee550888011a64fa3f35e666360ec8278597d8John Reck } 4614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 4714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 4864e445bf74bee2098781d608cedfd723d8cc88d3Chris Craikvoid CanvasState::initializeSaveStack( 4964e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik int viewportWidth, int viewportHeight, 5064e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik float clipLeft, float clipTop, 5169e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik float clipRight, float clipBottom, const Vector3& lightCenter) { 5264e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik if (mWidth != viewportWidth || mHeight != viewportHeight) { 5364e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mWidth = viewportWidth; 5464e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mHeight = viewportHeight; 55d9ee550888011a64fa3f35e666360ec8278597d8John Reck mFirstSnapshot.initializeViewport(viewportWidth, viewportHeight); 5664e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mCanvas.onViewportInitialized(); 5764e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik } 5864e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik 59d9ee550888011a64fa3f35e666360ec8278597d8John Reck freeAllSnapshots(); 60d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshot = allocSnapshot(&mFirstSnapshot, 6114e513058ed4168c94e015638d16f5f87fd8063aChris Craik SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 6214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom); 636b109c74982033d4a220cd10a0eab8b024b351c9Chris Craik mSnapshot->fbo = mCanvas.getTargetFbo(); 6469e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik mSnapshot->setRelativeLightCenter(lightCenter); 6514e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount = 1; 6614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 6714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 68d9ee550888011a64fa3f35e666360ec8278597d8John ReckSnapshot* CanvasState::allocSnapshot(Snapshot* previous, int savecount) { 69d9ee550888011a64fa3f35e666360ec8278597d8John Reck void* memory; 70d9ee550888011a64fa3f35e666360ec8278597d8John Reck if (mSnapshotPool) { 71d9ee550888011a64fa3f35e666360ec8278597d8John Reck memory = mSnapshotPool; 72d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPool = mSnapshotPool->previous; 73d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPoolCount--; 74d9ee550888011a64fa3f35e666360ec8278597d8John Reck } else { 75d9ee550888011a64fa3f35e666360ec8278597d8John Reck memory = malloc(sizeof(Snapshot)); 76d9ee550888011a64fa3f35e666360ec8278597d8John Reck } 77d9ee550888011a64fa3f35e666360ec8278597d8John Reck return new (memory) Snapshot(previous, savecount); 78d9ee550888011a64fa3f35e666360ec8278597d8John Reck} 79d9ee550888011a64fa3f35e666360ec8278597d8John Reck 80d9ee550888011a64fa3f35e666360ec8278597d8John Reckvoid CanvasState::freeSnapshot(Snapshot* snapshot) { 81d9ee550888011a64fa3f35e666360ec8278597d8John Reck snapshot->~Snapshot(); 82d9ee550888011a64fa3f35e666360ec8278597d8John Reck // Arbitrary number, just don't let this grown unbounded 83d9ee550888011a64fa3f35e666360ec8278597d8John Reck if (mSnapshotPoolCount > 10) { 84d9ee550888011a64fa3f35e666360ec8278597d8John Reck free((void*) snapshot); 85d9ee550888011a64fa3f35e666360ec8278597d8John Reck } else { 86d9ee550888011a64fa3f35e666360ec8278597d8John Reck snapshot->previous = mSnapshotPool; 87d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPool = snapshot; 88d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPoolCount++; 89d9ee550888011a64fa3f35e666360ec8278597d8John Reck } 90d9ee550888011a64fa3f35e666360ec8278597d8John Reck} 91d9ee550888011a64fa3f35e666360ec8278597d8John Reck 92d9ee550888011a64fa3f35e666360ec8278597d8John Reckvoid CanvasState::freeAllSnapshots() { 93d9ee550888011a64fa3f35e666360ec8278597d8John Reck while (mSnapshot != &mFirstSnapshot) { 94d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* temp = mSnapshot; 95d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshot = mSnapshot->previous; 96d9ee550888011a64fa3f35e666360ec8278597d8John Reck freeSnapshot(temp); 97d9ee550888011a64fa3f35e666360ec8278597d8John Reck } 98d9ee550888011a64fa3f35e666360ec8278597d8John Reck} 99d9ee550888011a64fa3f35e666360ec8278597d8John Reck 10014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 10114e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Save (layer) 10214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 10314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 105984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to save without side-effects 10614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 107984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save 10814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * stack, and ensures restoreToCount() doesn't call back into subclass overrides. 10914e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 110984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::saveSnapshot(int flags) { 111d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshot = allocSnapshot(mSnapshot, flags); 11214e513058ed4168c94e015638d16f5f87fd8063aChris Craik return mSaveCount++; 11314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 115984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::save(int flags) { 11614e513058ed4168c94e015638d16f5f87fd8063aChris Craik return saveSnapshot(flags); 11714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 11914e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 120984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to restore without side-effects. 12114e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 122984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreSnapshot() { 123d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* toRemove = mSnapshot; 124d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* toRestore = mSnapshot->previous; 12514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount--; 12714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = toRestore; 12814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 12914e513058ed4168c94e015638d16f5f87fd8063aChris Craik // subclass handles restore implementation 130984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mCanvas.onSnapshotRestored(*toRemove, *toRestore); 131d9ee550888011a64fa3f35e666360ec8278597d8John Reck 132d9ee550888011a64fa3f35e666360ec8278597d8John Reck freeSnapshot(toRemove); 13314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 135984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restore() { 13614e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSaveCount > 1) { 13714e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 13814e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 13914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 141984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreToCount(int saveCount) { 14214e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (saveCount < 1) saveCount = 1; 14314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 14414e513058ed4168c94e015638d16f5f87fd8063aChris Craik while (mSaveCount > saveCount) { 14514e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 14614e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 14714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 14914e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 15014e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Matrix 15114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 15214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 153984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::getMatrix(SkMatrix* matrix) const { 15414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->copyTo(*matrix); 15514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 15614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 157984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::translate(float dx, float dy, float dz) { 15814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->translate(dx, dy, dz); 15914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 16014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 161984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::rotate(float degrees) { 16214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); 16314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 16414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 165984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::scale(float sx, float sy) { 16614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->scale(sx, sy, 1.0f); 16714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 16814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 169984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::skew(float sx, float sy) { 17014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->skew(sx, sy); 17114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 17214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 173984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const SkMatrix& matrix) { 174139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mSnapshot->transform->load(matrix); 17514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 17614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 177984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const Matrix4& matrix) { 1787c85c54499994c687a833644f7f213e747fadb98Chris Craik *(mSnapshot->transform) = matrix; 17914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 18014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 181984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const SkMatrix& matrix) { 182139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mat4 transform(matrix); 18314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(transform); 18414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 18514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 186984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const Matrix4& matrix) { 18714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(matrix); 18814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 18914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 19014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 19114e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Clip 19214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 19314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 194984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 1954d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mSnapshot->clip(left, top, right, bottom, op); 1964d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 197487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 198d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 199d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 200984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) { 2014d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mSnapshot->clipPath(*path, op); 2024d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 203487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 204d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 205d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 206984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) { 2074d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mSnapshot->clipRegionTransformed(*region, op); 2084d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 209487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 210d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 21114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 212984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { 213af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik Rect bounds; 214af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik float radius; 215af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported 216af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 21779d26c72aa6f898125df2386054f6a293da4122aChris Craik bool outlineIsRounded = MathUtils::isPositive(radius); 21879d26c72aa6f898125df2386054f6a293da4122aChris Craik if (!outlineIsRounded || currentTransform()->isSimple()) { 219af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik // TODO: consider storing this rect separately, so that this can't be replaced with clip ops 220af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op); 221af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik } 22279d26c72aa6f898125df2386054f6a293da4122aChris Craik if (outlineIsRounded) { 223e83cbd451868a734bfac07ccd680d5617080b579Chris Craik setClippingRoundRect(allocator, bounds, radius, false); 22479d26c72aa6f898125df2386054f6a293da4122aChris Craik } 225deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik} 226deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 227984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingRoundRect(LinearAllocator& allocator, 228e83cbd451868a734bfac07ccd680d5617080b579Chris Craik const Rect& rect, float radius, bool highPriority) { 229e83cbd451868a734bfac07ccd680d5617080b579Chris Craik mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); 230af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik} 231af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 232fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craikvoid CanvasState::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) { 233fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik mSnapshot->setProjectionPathMask(allocator, path); 234fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik} 235af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 23614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 23714e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Quick Rejection 23814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 23914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 24114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Calculates whether content drawn within the passed bounds would be outside of, or intersect with 24214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * the clipRect. Does not modify the scissor. 24314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 24414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param clipRequired if not null, will be set to true if element intersects clip 24514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * (and wasn't rejected) 24614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 24714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param snapOut if set, the geometry will be treated as having an AA ramp. 24814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See Rect::snapGeometryToPixelBoundaries() 24914e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 250984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::calculateQuickRejectForScissor(float left, float top, 251deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik float right, float bottom, 252deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool* clipRequired, bool* roundRectClipRequired, 253deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool snapOut) const { 25414e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 25514e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 25614e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 25714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 25814e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 259d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 26014e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.snapGeometryToPixelBoundaries(snapOut); 26114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 262487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect clipRect(currentClipRect()); 26314e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 26414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 26514e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 26614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 26714e513058ed4168c94e015638d16f5f87fd8063aChris Craik // clip is required if geometry intersects clip rect 268deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (clipRequired) { 269deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik *clipRequired = !clipRect.contains(r); 270deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 271deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 272deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // round rect clip is required if RR clip exists, and geometry intersects its corners 273deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (roundRectClipRequired) { 274d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik *roundRectClipRequired = mSnapshot->roundRectClipState != nullptr 275deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik && mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r); 276deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 27714e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 27814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 27914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 280984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::quickRejectConservative(float left, float top, 28114e513058ed4168c94e015638d16f5f87fd8063aChris Craik float right, float bottom) const { 28214e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 28314e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 28414e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 28514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 28614e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 287d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 28814e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.roundOut(); // rounded out to be conservative 28914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 290487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect clipRect(currentClipRect()); 29114e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 29214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 29314e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 29414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 29514e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 29614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 29714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 298984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace uirenderer 299984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace android 300