CanvasState.cpp revision 64e445bf74bee2098781d608cedfd723d8cc88d3
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 3764e445bf74bee2098781d608cedfd723d8cc88d3Chris Craikvoid CanvasState::initializeSaveStack( 3864e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik int viewportWidth, int viewportHeight, 3964e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik float clipLeft, float clipTop, 4069e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik float clipRight, float clipBottom, const Vector3& lightCenter) { 4164e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik if (mWidth != viewportWidth || mHeight != viewportHeight) { 4264e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mWidth = viewportWidth; 4364e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mHeight = viewportHeight; 4464e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mFirstSnapshot->initializeViewport(viewportWidth, viewportHeight); 4564e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik mCanvas.onViewportInitialized(); 4664e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik } 4764e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik 4814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mFirstSnapshot, 4914e513058ed4168c94e015638d16f5f87fd8063aChris Craik SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 5014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom); 516b109c74982033d4a220cd10a0eab8b024b351c9Chris Craik mSnapshot->fbo = mCanvas.getTargetFbo(); 5269e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik mSnapshot->setRelativeLightCenter(lightCenter); 5314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount = 1; 5414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 5514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 5614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 5714e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Save (layer) 5814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 5914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 6014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 61984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to save without side-effects 6214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 63984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save 6414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * stack, and ensures restoreToCount() doesn't call back into subclass overrides. 6514e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 66984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::saveSnapshot(int flags) { 6714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mSnapshot, flags); 6814e513058ed4168c94e015638d16f5f87fd8063aChris Craik return mSaveCount++; 6914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 7014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 71984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonint CanvasState::save(int flags) { 7214e513058ed4168c94e015638d16f5f87fd8063aChris Craik return saveSnapshot(flags); 7314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 7414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 7514e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 76984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Guaranteed to restore without side-effects. 7714e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 78984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreSnapshot() { 7914e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRemove = mSnapshot; 8014e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRestore = mSnapshot->previous; 8114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount--; 8314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = toRestore; 8414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8514e513058ed4168c94e015638d16f5f87fd8063aChris Craik // subclass handles restore implementation 86984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mCanvas.onSnapshotRestored(*toRemove, *toRestore); 8714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 8814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 89984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restore() { 9014e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSaveCount > 1) { 9114e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 9214e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 9314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 9414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 95984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::restoreToCount(int saveCount) { 9614e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (saveCount < 1) saveCount = 1; 9714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9814e513058ed4168c94e015638d16f5f87fd8063aChris Craik while (mSaveCount > saveCount) { 9914e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 10014e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 10114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 10214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 10414e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Matrix 10514e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 10614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 107984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::getMatrix(SkMatrix* matrix) const { 10814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->copyTo(*matrix); 10914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 111984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::translate(float dx, float dy, float dz) { 11214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->translate(dx, dy, dz); 11314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 115984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::rotate(float degrees) { 11614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); 11714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 119984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::scale(float sx, float sy) { 12014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->scale(sx, sy, 1.0f); 12114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 123984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::skew(float sx, float sy) { 12414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->skew(sx, sy); 12514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 127984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const SkMatrix& matrix) { 128139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mSnapshot->transform->load(matrix); 12914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 131984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setMatrix(const Matrix4& matrix) { 1327c85c54499994c687a833644f7f213e747fadb98Chris Craik *(mSnapshot->transform) = matrix; 13314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 135984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const SkMatrix& matrix) { 136139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mat4 transform(matrix); 13714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(transform); 13814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 140984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::concatMatrix(const Matrix4& matrix) { 14114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(matrix); 14214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 14414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 14514e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Clip 14614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 14714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 148984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 1494d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mSnapshot->clip(left, top, right, bottom, op); 1504d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 151487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 152d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 153d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 154984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) { 1554d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mSnapshot->clipPath(*path, op); 1564d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 157487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 158d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 159d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 160984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) { 1614d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mSnapshot->clipRegionTransformed(*region, op); 1624d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mDirtyClip = true; 163487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return !mSnapshot->clipIsEmpty(); 164d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 16514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 166984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { 167af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik Rect bounds; 168af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik float radius; 169af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported 170af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 17179d26c72aa6f898125df2386054f6a293da4122aChris Craik bool outlineIsRounded = MathUtils::isPositive(radius); 17279d26c72aa6f898125df2386054f6a293da4122aChris Craik if (!outlineIsRounded || currentTransform()->isSimple()) { 173af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik // TODO: consider storing this rect separately, so that this can't be replaced with clip ops 174af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op); 175af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik } 17679d26c72aa6f898125df2386054f6a293da4122aChris Craik if (outlineIsRounded) { 177e83cbd451868a734bfac07ccd680d5617080b579Chris Craik setClippingRoundRect(allocator, bounds, radius, false); 17879d26c72aa6f898125df2386054f6a293da4122aChris Craik } 179deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik} 180deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 181984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonvoid CanvasState::setClippingRoundRect(LinearAllocator& allocator, 182e83cbd451868a734bfac07ccd680d5617080b579Chris Craik const Rect& rect, float radius, bool highPriority) { 183e83cbd451868a734bfac07ccd680d5617080b579Chris Craik mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); 184af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik} 185af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 186fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craikvoid CanvasState::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) { 187fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik mSnapshot->setProjectionPathMask(allocator, path); 188fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik} 189af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 19014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 19114e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Quick Rejection 19214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 19314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 19414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 19514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Calculates whether content drawn within the passed bounds would be outside of, or intersect with 19614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * the clipRect. Does not modify the scissor. 19714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 19814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param clipRequired if not null, will be set to true if element intersects clip 19914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * (and wasn't rejected) 20014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 20114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param snapOut if set, the geometry will be treated as having an AA ramp. 20214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See Rect::snapGeometryToPixelBoundaries() 20314e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 204984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::calculateQuickRejectForScissor(float left, float top, 205deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik float right, float bottom, 206deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool* clipRequired, bool* roundRectClipRequired, 207deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool snapOut) const { 20814e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 20914e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 21014e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 21114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 21214e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 213d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 21414e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.snapGeometryToPixelBoundaries(snapOut); 21514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 216487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect clipRect(currentClipRect()); 21714e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 21814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 21914e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 22014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 22114e513058ed4168c94e015638d16f5f87fd8063aChris Craik // clip is required if geometry intersects clip rect 222deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (clipRequired) { 223deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik *clipRequired = !clipRect.contains(r); 224deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 225deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 226deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // round rect clip is required if RR clip exists, and geometry intersects its corners 227deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (roundRectClipRequired) { 228d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik *roundRectClipRequired = mSnapshot->roundRectClipState != nullptr 229deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik && mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r); 230deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 23114e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 23214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 23314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 234984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonbool CanvasState::quickRejectConservative(float left, float top, 23514e513058ed4168c94e015638d16f5f87fd8063aChris Craik float right, float bottom) const { 23614e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 23714e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 23814e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 23914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24014e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 241d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 24214e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.roundOut(); // rounded out to be conservative 24314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 244487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect clipRect(currentClipRect()); 24514e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 24614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24714e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 24814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24914e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 25014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 25114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 252984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace uirenderer 253984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson} // namespace android 254