CanvasState.cpp revision eecff56fed5dd5206acfbc5007b4912081b36d3b
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 17eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita#include "Canvas.h" 18984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include "CanvasState.h" 19af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik#include "utils/MathUtils.h" 20af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 2114e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace android { 2214e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace uirenderer { 2314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 25984162fb7e4010b6e2908352dbff17ed47eecf06Tom HudsonCanvasState::CanvasState(CanvasStateClient& renderer) 26058fc640017c90120c599d378a4cbc55668b05b7Chris Craik : mDirtyClip(false) 27058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mWidth(-1) 28058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mHeight(-1) 29058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mSaveCount(1) 30984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson , mCanvas(renderer) 31d9ee550888011a64fa3f35e666360ec8278597d8John Reck , mSnapshot(&mFirstSnapshot) { 32d9ee550888011a64fa3f35e666360ec8278597d8John Reck} 33d9ee550888011a64fa3f35e666360ec8278597d8John Reck 34d9ee550888011a64fa3f35e666360ec8278597d8John ReckCanvasState::~CanvasState() { 35d9ee550888011a64fa3f35e666360ec8278597d8John Reck // First call freeSnapshot on all but mFirstSnapshot 36d9ee550888011a64fa3f35e666360ec8278597d8John Reck // to invoke all the dtors 37d9ee550888011a64fa3f35e666360ec8278597d8John Reck freeAllSnapshots(); 38984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson 39d9ee550888011a64fa3f35e666360ec8278597d8John Reck // Now actually release the memory 40d9ee550888011a64fa3f35e666360ec8278597d8John Reck while (mSnapshotPool) { 41d9ee550888011a64fa3f35e666360ec8278597d8John Reck void* temp = mSnapshotPool; 42d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPool = mSnapshotPool->previous; 43d9ee550888011a64fa3f35e666360ec8278597d8John Reck free(temp); 44d9ee550888011a64fa3f35e666360ec8278597d8John Reck } 4514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 4614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 47e4db79de127cfe961195f52907af8451026eaa20Chris Craikvoid CanvasState::initializeRecordingSaveStack(int viewportWidth, int viewportHeight) { 48e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (mWidth != viewportWidth || mHeight != viewportHeight) { 49e4db79de127cfe961195f52907af8451026eaa20Chris Craik mWidth = viewportWidth; 50e4db79de127cfe961195f52907af8451026eaa20Chris Craik mHeight = viewportHeight; 51e4db79de127cfe961195f52907af8451026eaa20Chris Craik mFirstSnapshot.initializeViewport(viewportWidth, viewportHeight); 52e4db79de127cfe961195f52907af8451026eaa20Chris Craik mCanvas.onViewportInitialized(); 53e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 54e4db79de127cfe961195f52907af8451026eaa20Chris Craik 55e4db79de127cfe961195f52907af8451026eaa20Chris Craik freeAllSnapshots(); 56eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita mSnapshot = allocSnapshot(&mFirstSnapshot, SaveFlags::MatrixClip); 57e4db79de127cfe961195f52907af8451026eaa20Chris Craik mSnapshot->setRelativeLightCenter(Vector3()); 58e4db79de127cfe961195f52907af8451026eaa20Chris Craik mSaveCount = 1; 59e4db79de127cfe961195f52907af8451026eaa20Chris Craik} 60e4db79de127cfe961195f52907af8451026eaa20Chris Craik 6164e445bf74bee2098781d608cedfd723d8cc88d3Chris Craikvoid CanvasState::initializeSaveStack( 6264e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik int viewportWidth, int viewportHeight, 6364e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik float clipLeft, float clipTop, 6469e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik float clipRight, float clipBottom, const Vector3& lightCenter) { 6564e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik if (mWidth != viewportWidth || mHeight != viewportHeight) { 6664e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mWidth = viewportWidth; 6764e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mHeight = viewportHeight; 68d9ee550888011a64fa3f35e666360ec8278597d8John Reck mFirstSnapshot.initializeViewport(viewportWidth, viewportHeight); 6964e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mCanvas.onViewportInitialized(); 7064e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik } 7164e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik 72d9ee550888011a64fa3f35e666360ec8278597d8John Reck freeAllSnapshots(); 73eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita mSnapshot = allocSnapshot(&mFirstSnapshot, SaveFlags::MatrixClip); 7414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom); 756b109c74982033d4a220cd10a0eab8b024b351c9Chris Craik mSnapshot->fbo = mCanvas.getTargetFbo(); 7669e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik mSnapshot->setRelativeLightCenter(lightCenter); 7714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount = 1; 7814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 7914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 80d9ee550888011a64fa3f35e666360ec8278597d8John ReckSnapshot* CanvasState::allocSnapshot(Snapshot* previous, int savecount) { 81d9ee550888011a64fa3f35e666360ec8278597d8John Reck void* memory; 82d9ee550888011a64fa3f35e666360ec8278597d8John Reck if (mSnapshotPool) { 83d9ee550888011a64fa3f35e666360ec8278597d8John Reck memory = mSnapshotPool; 84d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPool = mSnapshotPool->previous; 85d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPoolCount--; 86d9ee550888011a64fa3f35e666360ec8278597d8John Reck } else { 87d9ee550888011a64fa3f35e666360ec8278597d8John Reck memory = malloc(sizeof(Snapshot)); 88d9ee550888011a64fa3f35e666360ec8278597d8John Reck } 89d9ee550888011a64fa3f35e666360ec8278597d8John Reck return new (memory) Snapshot(previous, savecount); 90d9ee550888011a64fa3f35e666360ec8278597d8John Reck} 91d9ee550888011a64fa3f35e666360ec8278597d8John Reck 92d9ee550888011a64fa3f35e666360ec8278597d8John Reckvoid CanvasState::freeSnapshot(Snapshot* snapshot) { 93d9ee550888011a64fa3f35e666360ec8278597d8John Reck snapshot->~Snapshot(); 94d9ee550888011a64fa3f35e666360ec8278597d8John Reck // Arbitrary number, just don't let this grown unbounded 95d9ee550888011a64fa3f35e666360ec8278597d8John Reck if (mSnapshotPoolCount > 10) { 96d9ee550888011a64fa3f35e666360ec8278597d8John Reck free((void*) snapshot); 97d9ee550888011a64fa3f35e666360ec8278597d8John Reck } else { 98d9ee550888011a64fa3f35e666360ec8278597d8John Reck snapshot->previous = mSnapshotPool; 99d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPool = snapshot; 100d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshotPoolCount++; 101d9ee550888011a64fa3f35e666360ec8278597d8John Reck } 102d9ee550888011a64fa3f35e666360ec8278597d8John Reck} 103d9ee550888011a64fa3f35e666360ec8278597d8John Reck 104d9ee550888011a64fa3f35e666360ec8278597d8John Reckvoid CanvasState::freeAllSnapshots() { 105d9ee550888011a64fa3f35e666360ec8278597d8John Reck while (mSnapshot != &mFirstSnapshot) { 106d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* temp = mSnapshot; 107d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshot = mSnapshot->previous; 108d9ee550888011a64fa3f35e666360ec8278597d8John Reck freeSnapshot(temp); 109d9ee550888011a64fa3f35e666360ec8278597d8John Reck } 110d9ee550888011a64fa3f35e666360ec8278597d8John Reck} 111d9ee550888011a64fa3f35e666360ec8278597d8John Reck 11214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 11314e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Save (layer) 11414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 11514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 11614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 117984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to save without side-effects 11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 119984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save 12014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * stack, and ensures restoreToCount() doesn't call back into subclass overrides. 12114e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 122984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::saveSnapshot(int flags) { 123d9ee550888011a64fa3f35e666360ec8278597d8John Reck mSnapshot = allocSnapshot(mSnapshot, flags); 12414e513058ed4168c94e015638d16f5f87fd8063aChris Craik return mSaveCount++; 12514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 127984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::save(int flags) { 12814e513058ed4168c94e015638d16f5f87fd8063aChris Craik return saveSnapshot(flags); 12914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 13114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 132984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to restore without side-effects. 13314e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 134984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreSnapshot() { 135d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* toRemove = mSnapshot; 136d9ee550888011a64fa3f35e666360ec8278597d8John Reck Snapshot* toRestore = mSnapshot->previous; 13714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 13814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount--; 13914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = toRestore; 14014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 14114e513058ed4168c94e015638d16f5f87fd8063aChris Craik // subclass handles restore implementation 142984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mCanvas.onSnapshotRestored(*toRemove, *toRestore); 143d9ee550888011a64fa3f35e666360ec8278597d8John Reck 144d9ee550888011a64fa3f35e666360ec8278597d8John Reck freeSnapshot(toRemove); 14514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 147984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restore() { 14814e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSaveCount > 1) { 14914e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 15014e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 15114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 15214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 153984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreToCount(int saveCount) { 15414e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (saveCount < 1) saveCount = 1; 15514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 15614e513058ed4168c94e015638d16f5f87fd8063aChris Craik while (mSaveCount > saveCount) { 15714e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 15814e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 15914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 16014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 16114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 16214e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Matrix 16314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 16414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 165984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::getMatrix(SkMatrix* matrix) const { 16614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->copyTo(*matrix); 16714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 16814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 169984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::translate(float dx, float dy, float dz) { 17014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->translate(dx, dy, dz); 17114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 17214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 173984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::rotate(float degrees) { 17414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); 17514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 17614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 177984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::scale(float sx, float sy) { 17814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->scale(sx, sy, 1.0f); 17914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 18014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 181984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::skew(float sx, float sy) { 18214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->skew(sx, sy); 18314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 18414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 185984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const SkMatrix& matrix) { 186139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mSnapshot->transform->load(matrix); 18714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 18814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 189984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const Matrix4& matrix) { 1907c85c54499994c687a833644f7f213e747fadb98Chris Craik *(mSnapshot->transform) = matrix; 19114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 19214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 193984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const SkMatrix& matrix) { 194139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mat4 transform(matrix); 19514e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(transform); 19614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 19714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 198984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const Matrix4& matrix) { 19914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(matrix); 20014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 20114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 20214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 20314e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Clip 20414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 20514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 206984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 207a2a70723b8cbda4354d23f901f995623e819012cChris Craik mSnapshot->clip(Rect(left, top, right, bottom), op); 2084d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 209487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 210d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 211d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 212984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) { 2134d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mSnapshot->clipPath(*path, op); 2144d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 215487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 216d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 217d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 218984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) { 2194d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mSnapshot->clipRegionTransformed(*region, op); 2204d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 221487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 222d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 22314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 224984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { 225af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik Rect bounds; 226af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik float radius; 227af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported 228af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 22979d26c72aa6f898125df2386054f6a293da4122aChris Craik bool outlineIsRounded = MathUtils::isPositive(radius); 23079d26c72aa6f898125df2386054f6a293da4122aChris Craik if (!outlineIsRounded || currentTransform()->isSimple()) { 231af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik // TODO: consider storing this rect separately, so that this can't be replaced with clip ops 232af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op); 233af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik } 23479d26c72aa6f898125df2386054f6a293da4122aChris Craik if (outlineIsRounded) { 235e83cbd451868a734bfac07ccd680d5617080b579Chris Craik setClippingRoundRect(allocator, bounds, radius, false); 23679d26c72aa6f898125df2386054f6a293da4122aChris Craik } 237deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik} 238deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 239984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingRoundRect(LinearAllocator& allocator, 240e83cbd451868a734bfac07ccd680d5617080b579Chris Craik const Rect& rect, float radius, bool highPriority) { 241e83cbd451868a734bfac07ccd680d5617080b579Chris Craik mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); 242af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik} 243af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 244fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craikvoid CanvasState::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) { 245fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik mSnapshot->setProjectionPathMask(allocator, path); 246fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik} 247af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 24814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 24914e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Quick Rejection 25014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 25114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 25214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 25314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Calculates whether content drawn within the passed bounds would be outside of, or intersect with 25414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * the clipRect. Does not modify the scissor. 25514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 25614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param clipRequired if not null, will be set to true if element intersects clip 25714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * (and wasn't rejected) 25814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 25914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param snapOut if set, the geometry will be treated as having an AA ramp. 26014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See Rect::snapGeometryToPixelBoundaries() 26114e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 262984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::calculateQuickRejectForScissor(float left, float top, 263deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik float right, float bottom, 264deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool* clipRequired, bool* roundRectClipRequired, 265deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool snapOut) const { 26614e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 26714e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 26814e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 26914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 27014e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 271d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 27214e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.snapGeometryToPixelBoundaries(snapOut); 27314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 2746fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik Rect clipRect(currentRenderTargetClip()); 27514e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 27614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 27714e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 27814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 27914e513058ed4168c94e015638d16f5f87fd8063aChris Craik // clip is required if geometry intersects clip rect 280deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (clipRequired) { 281deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik *clipRequired = !clipRect.contains(r); 282deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 283deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 284deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // round rect clip is required if RR clip exists, and geometry intersects its corners 285deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (roundRectClipRequired) { 286d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik *roundRectClipRequired = mSnapshot->roundRectClipState != nullptr 287deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik && mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r); 288deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 28914e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 29014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 29114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 292984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::quickRejectConservative(float left, float top, 29314e513058ed4168c94e015638d16f5f87fd8063aChris Craik float right, float bottom) const { 29414e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 29514e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 29614e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 29714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 29814e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 299d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 30014e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.roundOut(); // rounded out to be conservative 30114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 3026fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik Rect clipRect(currentRenderTargetClip()); 30314e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 30414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 30514e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 30614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 30714e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 30814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 30914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 310984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace uirenderer 311984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace android 312