StatefulBaseRenderer.cpp revision 79d26c72aa6f898125df2386054f6a293da4122a
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 17deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik#define LOG_TAG "OpenGLRenderer" 18deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 1914e513058ed4168c94e015638d16f5f87fd8063aChris Craik#include <SkCanvas.h> 2014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 2114e513058ed4168c94e015638d16f5f87fd8063aChris Craik#include "StatefulBaseRenderer.h" 2214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 23af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik#include "utils/MathUtils.h" 24af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 2514e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace android { 2614e513058ed4168c94e015638d16f5f87fd8063aChris Craiknamespace uirenderer { 2714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 28058fc640017c90120c599d378a4cbc55668b05b7Chris CraikStatefulBaseRenderer::StatefulBaseRenderer() 29058fc640017c90120c599d378a4cbc55668b05b7Chris Craik : mDirtyClip(false) 30058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mWidth(-1) 31058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mHeight(-1) 32058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mSaveCount(1) 33058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mFirstSnapshot(new Snapshot) 34058fc640017c90120c599d378a4cbc55668b05b7Chris Craik , mSnapshot(mFirstSnapshot) { 3514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 3614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 3714e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop, 3869e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik float clipRight, float clipBottom, const Vector3& lightCenter) { 3914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mFirstSnapshot, 4014e513058ed4168c94e015638d16f5f87fd8063aChris Craik SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 4114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom); 4214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->fbo = getTargetFbo(); 4369e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik mSnapshot->setRelativeLightCenter(lightCenter); 4414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount = 1; 4514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 4614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 47797b95b26bbb7557678af78b9a2a61830158920fChris Craikvoid StatefulBaseRenderer::setViewport(int width, int height) { 4814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mWidth = width; 4914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mHeight = height; 50a64a2bef1048db5a742843f1e3bea9e80d0defc5Chris Craik mFirstSnapshot->initializeViewport(width, height); 51797b95b26bbb7557678af78b9a2a61830158920fChris Craik onViewportInitialized(); 52797b95b26bbb7557678af78b9a2a61830158920fChris Craik} 53797b95b26bbb7557678af78b9a2a61830158920fChris Craik 5414e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 5514e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Save (layer) 5614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 5714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 5814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 5914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Non-virtual implementation of save, guaranteed to save without side-effects 6014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 6114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * The approach here and in restoreSnapshot(), allows subclasses to directly manipulate the save 6214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * stack, and ensures restoreToCount() doesn't call back into subclass overrides. 6314e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 6414e513058ed4168c94e015638d16f5f87fd8063aChris Craikint StatefulBaseRenderer::saveSnapshot(int flags) { 6514e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mSnapshot, flags); 6614e513058ed4168c94e015638d16f5f87fd8063aChris Craik return mSaveCount++; 6714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 6814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 6914e513058ed4168c94e015638d16f5f87fd8063aChris Craikint StatefulBaseRenderer::save(int flags) { 7014e513058ed4168c94e015638d16f5f87fd8063aChris Craik return saveSnapshot(flags); 7114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 7214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 7314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 7414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Non-virtual implementation of restore, guaranteed to restore without side-effects. 7514e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 7614e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restoreSnapshot() { 7714e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRemove = mSnapshot; 7814e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRestore = mSnapshot->previous; 7914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount--; 8114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = toRestore; 8214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8314e513058ed4168c94e015638d16f5f87fd8063aChris Craik // subclass handles restore implementation 8414e513058ed4168c94e015638d16f5f87fd8063aChris Craik onSnapshotRestored(*toRemove, *toRestore); 8514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 8614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8714e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restore() { 8814e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSaveCount > 1) { 8914e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 9014e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 9114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 9214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9314e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restoreToCount(int saveCount) { 9414e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (saveCount < 1) saveCount = 1; 9514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9614e513058ed4168c94e015638d16f5f87fd8063aChris Craik while (mSaveCount > saveCount) { 9714e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 9814e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 9914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 10014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 10214e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Matrix 10314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 10414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10505f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craikvoid StatefulBaseRenderer::getMatrix(Matrix4* matrix) const { 10605f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik matrix->load(*(mSnapshot->transform)); 10705f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik} 10805f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik 10914e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::getMatrix(SkMatrix* matrix) const { 11014e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->copyTo(*matrix); 11114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 11314e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::translate(float dx, float dy, float dz) { 11414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->translate(dx, dy, dz); 11514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 11714e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::rotate(float degrees) { 11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); 11914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 12114e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::scale(float sx, float sy) { 12214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->scale(sx, sy, 1.0f); 12314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 12514e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::skew(float sx, float sy) { 12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->skew(sx, sy); 12714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 129139088228faa7f3c446af7387e017933998a5570Derek Sollenbergervoid StatefulBaseRenderer::setMatrix(const SkMatrix& matrix) { 130139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mSnapshot->transform->load(matrix); 13114e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 13314e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::setMatrix(const Matrix4& matrix) { 13414e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->load(matrix); 13514e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 137139088228faa7f3c446af7387e017933998a5570Derek Sollenbergervoid StatefulBaseRenderer::concatMatrix(const SkMatrix& matrix) { 138139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mat4 transform(matrix); 13914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(transform); 14014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 14214e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { 14314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(matrix); 14414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 14614e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 14714e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Clip 14814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 14914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 150d6b65f67717025b1162f86f04e2caa5723566cacChris Craikbool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 151d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (CC_LIKELY(currentTransform()->rectToRect())) { 152d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op); 153d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 154d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 155d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 156d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkPath path; 157d6b65f67717025b1162f86f04e2caa5723566cacChris Craik path.addRect(left, top, right, bottom); 158d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 159d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return StatefulBaseRenderer::clipPath(&path, op); 160d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 161d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 162d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikbool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { 163d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkMatrix transform; 164d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->copyTo(transform); 165d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 166d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkPath transformed; 167d6b65f67717025b1162f86f04e2caa5723566cacChris Craik path->transform(transform, &transformed); 168d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 169d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkRegion clip; 170d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (!mSnapshot->previous->clipRegion->isEmpty()) { 171d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRegion(*mSnapshot->previous->clipRegion); 172d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } else { 173d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (mSnapshot->previous == firstSnapshot()) { 174d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRect(0, 0, getWidth(), getHeight()); 175d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } else { 176d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect* bounds = mSnapshot->previous->clipRect; 177d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom); 178d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 179d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 180d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 181d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkRegion region; 182d6b65f67717025b1162f86f04e2caa5723566cacChris Craik region.setPath(transformed, clip); 183d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 18462d307c2402777d5e53b4590af5f32f8c55afd81Chris Craik // region is the transformed input path, masked by the previous clip 185d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clipRegionTransformed(region, op); 186d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 187d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 188d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 189d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikbool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { 190d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op); 191d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 192d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 19314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 194deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craikvoid StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { 195af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik Rect bounds; 196af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik float radius; 197af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported 198af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 19979d26c72aa6f898125df2386054f6a293da4122aChris Craik bool outlineIsRounded = MathUtils::isPositive(radius); 20079d26c72aa6f898125df2386054f6a293da4122aChris Craik if (!outlineIsRounded || currentTransform()->isSimple()) { 201af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik // TODO: consider storing this rect separately, so that this can't be replaced with clip ops 202af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op); 203af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik } 20479d26c72aa6f898125df2386054f6a293da4122aChris Craik if (outlineIsRounded) { 20579d26c72aa6f898125df2386054f6a293da4122aChris Craik setClippingRoundRect(allocator, bounds, radius); 20679d26c72aa6f898125df2386054f6a293da4122aChris Craik } 207deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik} 208deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 209af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craikvoid StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, 210af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik const Rect& rect, float radius) { 211af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik mSnapshot->setClippingRoundRect(allocator, rect, radius); 212af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik} 213af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 214af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 21514e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 21614e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Quick Rejection 21714e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 21814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 21914e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 22014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Calculates whether content drawn within the passed bounds would be outside of, or intersect with 22114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * the clipRect. Does not modify the scissor. 22214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 22314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param clipRequired if not null, will be set to true if element intersects clip 22414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * (and wasn't rejected) 22514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 22614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param snapOut if set, the geometry will be treated as having an AA ramp. 22714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See Rect::snapGeometryToPixelBoundaries() 22814e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 22914e513058ed4168c94e015638d16f5f87fd8063aChris Craikbool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, 230deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik float right, float bottom, 231deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool* clipRequired, bool* roundRectClipRequired, 232deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool snapOut) const { 23314e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 23414e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 23514e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 23614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 23714e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 238d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 23914e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.snapGeometryToPixelBoundaries(snapOut); 24014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 241d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect clipRect(*currentClipRect()); 24214e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 24314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24414e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 24514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24614e513058ed4168c94e015638d16f5f87fd8063aChris Craik // clip is required if geometry intersects clip rect 247deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (clipRequired) { 248deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik *clipRequired = !clipRect.contains(r); 249deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 250deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 251deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // round rect clip is required if RR clip exists, and geometry intersects its corners 252deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (roundRectClipRequired) { 253deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik *roundRectClipRequired = mSnapshot->roundRectClipState != NULL 254deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik && mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r); 255deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 25614e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 25714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 25814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 25914e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 26014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Returns false if drawing won't be clipped out. 26114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 26214e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Makes the decision conservatively, by rounding out the mapped rect before comparing with the 26314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but 26414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * rejection is still desired. 26514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 26614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * This function, unlike quickRejectSetupScissor, should be used where precise geometry information 26714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass 26814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * rejection where precise rejection isn't important, or precise information isn't available. 26914e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 27014e513058ed4168c94e015638d16f5f87fd8063aChris Craikbool StatefulBaseRenderer::quickRejectConservative(float left, float top, 27114e513058ed4168c94e015638d16f5f87fd8063aChris Craik float right, float bottom) const { 27214e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 27314e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 27414e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 27514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 27614e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 277d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 27814e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.roundOut(); // rounded out to be conservative 27914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 280d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect clipRect(*currentClipRect()); 28114e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 28214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 28314e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 28414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 28514e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 28614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 28714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 28814e513058ed4168c94e015638d16f5f87fd8063aChris Craik}; // namespace uirenderer 28914e513058ed4168c94e015638d16f5f87fd8063aChris Craik}; // namespace android 290