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