StatefulBaseRenderer.cpp revision a64a2bef1048db5a742843f1e3bea9e80d0defc5
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 1914e513058ed4168c94e015638d16f5f87fd8063aChris Craik#include "StatefulBaseRenderer.h" 2014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 2114e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace android { 2214e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace uirenderer { 2314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 2414e513058ed4168c94e015638d16f5f87fd8063aChris CraikStatefulBaseRenderer::StatefulBaseRenderer() : 25d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip(false), mWidth(-1), mHeight(-1), 2614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount(1), mFirstSnapshot(new Snapshot), mSnapshot(mFirstSnapshot) { 2714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 2814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 2914e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop, 3014e513058ed4168c94e015638d16f5f87fd8063aChris Craik float clipRight, float clipBottom) { 3114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mFirstSnapshot, 3214e513058ed4168c94e015638d16f5f87fd8063aChris Craik SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 3314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom); 3414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->fbo = getTargetFbo(); 3514e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount = 1; 3614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 3714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 3814e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::initializeViewport(int width, int height) { 3914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mWidth = width; 4014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mHeight = height; 41a64a2bef1048db5a742843f1e3bea9e80d0defc5Chris Craik mFirstSnapshot->initializeViewport(width, height); 4214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 4314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 4414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 4514e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Save (layer) 4614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 4714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 4814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 4914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Non-virtual implementation of save, guaranteed to save without side-effects 5014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 5114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * The approach here and in restoreSnapshot(), allows subclasses to directly manipulate the save 5214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * stack, and ensures restoreToCount() doesn't call back into subclass overrides. 5314e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 5414e513058ed4168c94e015638d16f5f87fd8063aChris Craikint StatefulBaseRenderer::saveSnapshot(int flags) { 5514e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mSnapshot, flags); 5614e513058ed4168c94e015638d16f5f87fd8063aChris Craik return mSaveCount++; 5714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 5814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 5914e513058ed4168c94e015638d16f5f87fd8063aChris Craikint StatefulBaseRenderer::save(int flags) { 6014e513058ed4168c94e015638d16f5f87fd8063aChris Craik return saveSnapshot(flags); 6114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 6214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 6314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 6414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Non-virtual implementation of restore, guaranteed to restore without side-effects. 6514e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 6614e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restoreSnapshot() { 6714e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRemove = mSnapshot; 6814e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRestore = mSnapshot->previous; 6914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 7014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount--; 7114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = toRestore; 7214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 7314e513058ed4168c94e015638d16f5f87fd8063aChris Craik // subclass handles restore implementation 7414e513058ed4168c94e015638d16f5f87fd8063aChris Craik onSnapshotRestored(*toRemove, *toRestore); 7514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 7614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 7714e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restore() { 7814e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSaveCount > 1) { 7914e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 8014e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 8114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 8214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8314e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restoreToCount(int saveCount) { 8414e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (saveCount < 1) saveCount = 1; 8514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8614e513058ed4168c94e015638d16f5f87fd8063aChris Craik while (mSaveCount > saveCount) { 8714e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 8814e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 8914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 9014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 9214e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Matrix 9314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 9414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9514e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::getMatrix(SkMatrix* matrix) const { 9614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->copyTo(*matrix); 9714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 9814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9914e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::translate(float dx, float dy, float dz) { 10014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->translate(dx, dy, dz); 10114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 10214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10314e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::rotate(float degrees) { 10414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); 10514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 10614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10714e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::scale(float sx, float sy) { 10814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->scale(sx, sy, 1.0f); 10914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 11114e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::skew(float sx, float sy) { 11214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->skew(sx, sy); 11314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 115d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid StatefulBaseRenderer::setMatrix(const SkMatrix* matrix) { 11614e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (matrix) { 11714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->load(*matrix); 11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik } else { 11914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->loadIdentity(); 12014e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 12114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 12314e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::setMatrix(const Matrix4& matrix) { 12414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->load(matrix); 12514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 127d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikvoid StatefulBaseRenderer::concatMatrix(const SkMatrix* matrix) { 12814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mat4 transform(*matrix); 12914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(transform); 13014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 13214e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { 13314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(matrix); 13414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 13614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 13714e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Clip 13814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 13914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 140d6b65f67717025b1162f86f04e2caa5723566cacChris Craikbool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 141d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (CC_LIKELY(currentTransform()->rectToRect())) { 142d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op); 143d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 144d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 145d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 146d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkPath path; 147d6b65f67717025b1162f86f04e2caa5723566cacChris Craik path.addRect(left, top, right, bottom); 148d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 149d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return StatefulBaseRenderer::clipPath(&path, op); 150d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 151d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 152d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikbool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { 153d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkMatrix transform; 154d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->copyTo(transform); 155d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 156d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkPath transformed; 157d6b65f67717025b1162f86f04e2caa5723566cacChris Craik path->transform(transform, &transformed); 158d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 159d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkRegion clip; 160d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (!mSnapshot->previous->clipRegion->isEmpty()) { 161d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRegion(*mSnapshot->previous->clipRegion); 162d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } else { 163d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (mSnapshot->previous == firstSnapshot()) { 164d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRect(0, 0, getWidth(), getHeight()); 165d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } else { 166d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect* bounds = mSnapshot->previous->clipRect; 167d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom); 168d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 169d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 170d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 171d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkRegion region; 172d6b65f67717025b1162f86f04e2caa5723566cacChris Craik region.setPath(transformed, clip); 173d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 174d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clipRegionTransformed(region, op); 175d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 176d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 177d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 178d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikbool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { 179d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op); 180d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 181d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 18214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 18314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 18414e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Quick Rejection 18514e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 18614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 18714e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 18814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Calculates whether content drawn within the passed bounds would be outside of, or intersect with 18914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * the clipRect. Does not modify the scissor. 19014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 19114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param clipRequired if not null, will be set to true if element intersects clip 19214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * (and wasn't rejected) 19314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 19414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param snapOut if set, the geometry will be treated as having an AA ramp. 19514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See Rect::snapGeometryToPixelBoundaries() 19614e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 19714e513058ed4168c94e015638d16f5f87fd8063aChris Craikbool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, 19814e513058ed4168c94e015638d16f5f87fd8063aChris Craik float right, float bottom, bool* clipRequired, bool snapOut) const { 19914e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 20014e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 20114e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 20214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 20314e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 204d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 20514e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.snapGeometryToPixelBoundaries(snapOut); 20614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 207d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect clipRect(*currentClipRect()); 20814e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 20914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 21014e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 21114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 21214e513058ed4168c94e015638d16f5f87fd8063aChris Craik // clip is required if geometry intersects clip rect 21314e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (clipRequired) *clipRequired = !clipRect.contains(r); 21414e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 21514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 21614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 21714e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 21814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Returns false if drawing won't be clipped out. 21914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 22014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Makes the decision conservatively, by rounding out the mapped rect before comparing with the 22114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but 22214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * rejection is still desired. 22314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 22414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * This function, unlike quickRejectSetupScissor, should be used where precise geometry information 22514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass 22614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * rejection where precise rejection isn't important, or precise information isn't available. 22714e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 22814e513058ed4168c94e015638d16f5f87fd8063aChris Craikbool StatefulBaseRenderer::quickRejectConservative(float left, float top, 22914e513058ed4168c94e015638d16f5f87fd8063aChris Craik float right, float bottom) const { 23014e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 23114e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 23214e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 23314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 23414e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 235d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 23614e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.roundOut(); // rounded out to be conservative 23714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 238d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect clipRect(*currentClipRect()); 23914e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 24014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24114e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 24214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24314e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 24414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 24514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24614e513058ed4168c94e015638d16f5f87fd8063aChris Craik}; // namespace uirenderer 24714e513058ed4168c94e015638d16f5f87fd8063aChris Craik}; // namespace android 248