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(); 52284b24358410cb0200e525a5ba36994090c83f20Chris Craik 53284b24358410cb0200e525a5ba36994090c83f20Chris Craik // create a temporary 1st snapshot, so old snapshots are released, 54284b24358410cb0200e525a5ba36994090c83f20Chris Craik // and viewport can be queried safely. 55284b24358410cb0200e525a5ba36994090c83f20Chris Craik // TODO: remove, combine viewport + save stack initialization 56284b24358410cb0200e525a5ba36994090c83f20Chris Craik mSnapshot = new Snapshot(mFirstSnapshot, 57284b24358410cb0200e525a5ba36994090c83f20Chris Craik SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 58284b24358410cb0200e525a5ba36994090c83f20Chris Craik mSaveCount = 1; 59797b95b26bbb7557678af78b9a2a61830158920fChris Craik} 60797b95b26bbb7557678af78b9a2a61830158920fChris Craik 6114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 6214e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Save (layer) 6314e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 6414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 6514e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 6614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Non-virtual implementation of save, guaranteed to save without side-effects 6714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 6814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * The approach here and in restoreSnapshot(), allows subclasses to directly manipulate the save 6914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * stack, and ensures restoreToCount() doesn't call back into subclass overrides. 7014e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 7114e513058ed4168c94e015638d16f5f87fd8063aChris Craikint StatefulBaseRenderer::saveSnapshot(int flags) { 7214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = new Snapshot(mSnapshot, flags); 7314e513058ed4168c94e015638d16f5f87fd8063aChris Craik return mSaveCount++; 7414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 7514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 7614e513058ed4168c94e015638d16f5f87fd8063aChris Craikint StatefulBaseRenderer::save(int flags) { 7714e513058ed4168c94e015638d16f5f87fd8063aChris Craik return saveSnapshot(flags); 7814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 7914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 8114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Non-virtual implementation of restore, guaranteed to restore without side-effects. 8214e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 8314e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restoreSnapshot() { 8414e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRemove = mSnapshot; 8514e513058ed4168c94e015638d16f5f87fd8063aChris Craik sp<Snapshot> toRestore = mSnapshot->previous; 8614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 8714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSaveCount--; 8814e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot = toRestore; 8914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9014e513058ed4168c94e015638d16f5f87fd8063aChris Craik // subclass handles restore implementation 9114e513058ed4168c94e015638d16f5f87fd8063aChris Craik onSnapshotRestored(*toRemove, *toRestore); 9214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 9314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 9414e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restore() { 9514e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSaveCount > 1) { 9614e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 9714e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 9814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 9914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10014e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::restoreToCount(int saveCount) { 10114e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (saveCount < 1) saveCount = 1; 10214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10314e513058ed4168c94e015638d16f5f87fd8063aChris Craik while (mSaveCount > saveCount) { 10414e513058ed4168c94e015638d16f5f87fd8063aChris Craik restoreSnapshot(); 10514e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 10614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 10714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 10814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 10914e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Matrix 11014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 11114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 11214e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::getMatrix(SkMatrix* matrix) const { 11314e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->copyTo(*matrix); 11414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 11614e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::translate(float dx, float dy, float dz) { 11714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->translate(dx, dy, dz); 11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 11914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 12014e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::rotate(float degrees) { 12114e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f); 12214e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 12414e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::scale(float sx, float sy) { 12514e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->scale(sx, sy, 1.0f); 12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 12714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 12814e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::skew(float sx, float sy) { 12914e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->skew(sx, sy); 13014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 132139088228faa7f3c446af7387e017933998a5570Derek Sollenbergervoid StatefulBaseRenderer::setMatrix(const SkMatrix& matrix) { 133139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mSnapshot->transform->load(matrix); 13414e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 13614e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::setMatrix(const Matrix4& matrix) { 13714e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->load(matrix); 13814e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 13914e513058ed4168c94e015638d16f5f87fd8063aChris Craik 140139088228faa7f3c446af7387e017933998a5570Derek Sollenbergervoid StatefulBaseRenderer::concatMatrix(const SkMatrix& matrix) { 141139088228faa7f3c446af7387e017933998a5570Derek Sollenberger mat4 transform(matrix); 14214e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(transform); 14314e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14414e513058ed4168c94e015638d16f5f87fd8063aChris Craik 14514e513058ed4168c94e015638d16f5f87fd8063aChris Craikvoid StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) { 14614e513058ed4168c94e015638d16f5f87fd8063aChris Craik mSnapshot->transform->multiply(matrix); 14714e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 14814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 14914e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 15014e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Clip 15114e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 15214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 153d6b65f67717025b1162f86f04e2caa5723566cacChris Craikbool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 154d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (CC_LIKELY(currentTransform()->rectToRect())) { 155d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op); 156d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 157d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 158d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 159d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkPath path; 160d6b65f67717025b1162f86f04e2caa5723566cacChris Craik path.addRect(left, top, right, bottom); 161d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 162d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return StatefulBaseRenderer::clipPath(&path, op); 163d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 164d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 165d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikbool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) { 166d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkMatrix transform; 167d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->copyTo(transform); 168d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 169d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkPath transformed; 170d6b65f67717025b1162f86f04e2caa5723566cacChris Craik path->transform(transform, &transformed); 171d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 172d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkRegion clip; 173d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (!mSnapshot->previous->clipRegion->isEmpty()) { 174d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRegion(*mSnapshot->previous->clipRegion); 175d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } else { 176d6b65f67717025b1162f86f04e2caa5723566cacChris Craik if (mSnapshot->previous == firstSnapshot()) { 177d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRect(0, 0, getWidth(), getHeight()); 178d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } else { 179d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect* bounds = mSnapshot->previous->clipRect; 180d6b65f67717025b1162f86f04e2caa5723566cacChris Craik clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom); 181d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 182d6b65f67717025b1162f86f04e2caa5723566cacChris Craik } 183d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 184d6b65f67717025b1162f86f04e2caa5723566cacChris Craik SkRegion region; 185d6b65f67717025b1162f86f04e2caa5723566cacChris Craik region.setPath(transformed, clip); 186d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 18762d307c2402777d5e53b4590af5f32f8c55afd81Chris Craik // region is the transformed input path, masked by the previous clip 188d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clipRegionTransformed(region, op); 189d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 190d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 191d6b65f67717025b1162f86f04e2caa5723566cacChris Craik 192d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikbool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { 193d6b65f67717025b1162f86f04e2caa5723566cacChris Craik mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op); 194d6b65f67717025b1162f86f04e2caa5723566cacChris Craik return !mSnapshot->clipRect->isEmpty(); 195d6b65f67717025b1162f86f04e2caa5723566cacChris Craik} 19614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 197deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craikvoid StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { 198af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik Rect bounds; 199af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik float radius; 200af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported 201af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 20279d26c72aa6f898125df2386054f6a293da4122aChris Craik bool outlineIsRounded = MathUtils::isPositive(radius); 20379d26c72aa6f898125df2386054f6a293da4122aChris Craik if (!outlineIsRounded || currentTransform()->isSimple()) { 204af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik // TODO: consider storing this rect separately, so that this can't be replaced with clip ops 205af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op); 206af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik } 20779d26c72aa6f898125df2386054f6a293da4122aChris Craik if (outlineIsRounded) { 208e83cbd451868a734bfac07ccd680d5617080b579Chris Craik setClippingRoundRect(allocator, bounds, radius, false); 20979d26c72aa6f898125df2386054f6a293da4122aChris Craik } 210deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik} 211deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 212af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craikvoid StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, 213e83cbd451868a734bfac07ccd680d5617080b579Chris Craik const Rect& rect, float radius, bool highPriority) { 214e83cbd451868a734bfac07ccd680d5617080b579Chris Craik mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); 215af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik} 216af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 217af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik 21814e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 21914e513058ed4168c94e015638d16f5f87fd8063aChris Craik// Quick Rejection 22014e513058ed4168c94e015638d16f5f87fd8063aChris Craik/////////////////////////////////////////////////////////////////////////////// 22114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 22214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 22314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Calculates whether content drawn within the passed bounds would be outside of, or intersect with 22414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * the clipRect. Does not modify the scissor. 22514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 22614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param clipRequired if not null, will be set to true if element intersects clip 22714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * (and wasn't rejected) 22814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 22914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * @param snapOut if set, the geometry will be treated as having an AA ramp. 23014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * See Rect::snapGeometryToPixelBoundaries() 23114e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 23214e513058ed4168c94e015638d16f5f87fd8063aChris Craikbool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top, 233deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik float right, float bottom, 234deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool* clipRequired, bool* roundRectClipRequired, 235deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik bool snapOut) 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.snapGeometryToPixelBoundaries(snapOut); 24314e513058ed4168c94e015638d16f5f87fd8063aChris Craik 244d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect clipRect(*currentClipRect()); 24514e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 24614e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24714e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 24814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 24914e513058ed4168c94e015638d16f5f87fd8063aChris Craik // clip is required if geometry intersects clip rect 250deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (clipRequired) { 251deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik *clipRequired = !clipRect.contains(r); 252deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 253deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 254deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // round rect clip is required if RR clip exists, and geometry intersects its corners 255deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik if (roundRectClipRequired) { 256deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik *roundRectClipRequired = mSnapshot->roundRectClipState != NULL 257deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik && mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r); 258deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 25914e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 26014e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 26114e513058ed4168c94e015638d16f5f87fd8063aChris Craik 26214e513058ed4168c94e015638d16f5f87fd8063aChris Craik/** 26314e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Returns false if drawing won't be clipped out. 26414e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 26514e513058ed4168c94e015638d16f5f87fd8063aChris Craik * Makes the decision conservatively, by rounding out the mapped rect before comparing with the 26614e513058ed4168c94e015638d16f5f87fd8063aChris Craik * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but 26714e513058ed4168c94e015638d16f5f87fd8063aChris Craik * rejection is still desired. 26814e513058ed4168c94e015638d16f5f87fd8063aChris Craik * 26914e513058ed4168c94e015638d16f5f87fd8063aChris Craik * This function, unlike quickRejectSetupScissor, should be used where precise geometry information 27014e513058ed4168c94e015638d16f5f87fd8063aChris Craik * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass 27114e513058ed4168c94e015638d16f5f87fd8063aChris Craik * rejection where precise rejection isn't important, or precise information isn't available. 27214e513058ed4168c94e015638d16f5f87fd8063aChris Craik */ 27314e513058ed4168c94e015638d16f5f87fd8063aChris Craikbool StatefulBaseRenderer::quickRejectConservative(float left, float top, 27414e513058ed4168c94e015638d16f5f87fd8063aChris Craik float right, float bottom) const { 27514e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (mSnapshot->isIgnored() || bottom <= top || right <= left) { 27614e513058ed4168c94e015638d16f5f87fd8063aChris Craik return true; 27714e513058ed4168c94e015638d16f5f87fd8063aChris Craik } 27814e513058ed4168c94e015638d16f5f87fd8063aChris Craik 27914e513058ed4168c94e015638d16f5f87fd8063aChris Craik Rect r(left, top, right, bottom); 280d6b65f67717025b1162f86f04e2caa5723566cacChris Craik currentTransform()->mapRect(r); 28114e513058ed4168c94e015638d16f5f87fd8063aChris Craik r.roundOut(); // rounded out to be conservative 28214e513058ed4168c94e015638d16f5f87fd8063aChris Craik 283d6b65f67717025b1162f86f04e2caa5723566cacChris Craik Rect clipRect(*currentClipRect()); 28414e513058ed4168c94e015638d16f5f87fd8063aChris Craik clipRect.snapToPixelBoundaries(); 28514e513058ed4168c94e015638d16f5f87fd8063aChris Craik 28614e513058ed4168c94e015638d16f5f87fd8063aChris Craik if (!clipRect.intersects(r)) return true; 28714e513058ed4168c94e015638d16f5f87fd8063aChris Craik 28814e513058ed4168c94e015638d16f5f87fd8063aChris Craik return false; 28914e513058ed4168c94e015638d16f5f87fd8063aChris Craik} 29014e513058ed4168c94e015638d16f5f87fd8063aChris Craik 29114e513058ed4168c94e015638d16f5f87fd8063aChris Craik}; // namespace uirenderer 29214e513058ed4168c94e015638d16f5f87fd8063aChris Craik}; // namespace android 293