DisplayListOp.h revision bf6f0f260886a04a1680c7f9917124a751322ca4
12af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik/* 27031ff68bb998dbbd7caf3b2fd75eef747a86725Romain Guy * Copyright (C) 2013 The Android Open Source Project 32af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * 42af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 52af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * you may not use this file except in compliance with the License. 62af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * You may obtain a copy of the License at 72af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * 82af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * http://www.apache.org/licenses/LICENSE-2.0 92af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * 102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * Unless required by applicable law or agreed to in writing, software 112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * distributed under the License is distributed on an "AS IS" BASIS, 122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * See the License for the specific language governing permissions and 142af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * limitations under the License. 152af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik */ 162af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#ifndef ANDROID_HWUI_DISPLAY_OPERATION_H 182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#define ANDROID_HWUI_DISPLAY_OPERATION_H 192af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#include "OpenGLRenderer.h" 213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "AssetAtlas.h" 22c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include "DeferredDisplayList.h" 23db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik#include "DisplayListCanvas.h" 242dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "GammaFontRenderer.h" 252dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "Patch.h" 262dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "RenderNode.h" 2765fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik#include "renderstate/RenderState.h" 283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "UvMapper.h" 292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#include "utils/LinearAllocator.h" 308dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson#include "utils/PaintUtils.h" 312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 32df72b63928cc1492b72ba9a4e99d5e714f93ccc6Chris Craik#include <algorithm> 33df72b63928cc1492b72ba9a4e99d5e714f93ccc6Chris Craik 3465fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik#include <SkColor.h> 3565fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik#include <SkPath.h> 3665fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik#include <SkPathOps.h> 3765fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik#include <SkXfermode.h> 3865fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik 3965fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik#include <private/hwui/DrawGlInfo.h> 4065fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik 412af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik// Use OP_LOG for logging with arglist, OP_LOGS if just printing char* 4228ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik#define OP_LOGS(s) OP_LOG("%s", (s)) 433dc553babe515fbf9bd042dd63a792e5de578ecdChris Craik#define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ ) 442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 452af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craiknamespace android { 462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craiknamespace uirenderer { 472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik/** 492af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * Structure for storing canvas operations when they are recorded into a DisplayList, so that they 502af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * may be replayed to an OpenGLRenderer. 512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * 522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * To avoid individual memory allocations, DisplayListOps may only be allocated into a 532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * LinearAllocator's managed memory buffers. Each pointer held by a DisplayListOp is either a 542af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * pointer into memory also allocated in the LinearAllocator (mostly for text and float buffers) or 552af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * references a externally refcounted object (Sk... and Skia... objects). ~DisplayListOp() is 562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * never called as LinearAllocators are simply discarded, so no memory management should be done in 572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik * this class. 582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik */ 592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DisplayListOp { 602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted. 622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik // standard new() intentionally not implemented, and delete/deconstructor should never be used. 6351d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik virtual ~DisplayListOp() { LOG_ALWAYS_FATAL("Destructor not supported"); } 6451d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik static void operator delete(void* ptr) { LOG_ALWAYS_FATAL("delete not supported"); } 6551d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik static void* operator new(size_t size) = delete; /** PURPOSELY OMITTED **/ 662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik static void* operator new(size_t size, LinearAllocator& allocator) { 672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik return allocator.alloc(size); 682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik enum OpLogFlag { 712af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik kOpLogFlag_Recurse = 0x1, 722af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik kOpLogFlag_JSON = 0x2 // TODO: add? 732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik }; 742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 75dd671599bed9d3ca28e2c744e8c224e1e15bc914Chet Haase virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, 76dd671599bed9d3ca28e2c744e8c224e1e15bc914Chet Haase bool useQuickReject) = 0; 77c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 78dd671599bed9d3ca28e2c744e8c224e1e15bc914Chet Haase virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, 79dd671599bed9d3ca28e2c744e8c224e1e15bc914Chet Haase bool useQuickReject) = 0; 80ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 81c5493fb7fa1f6995955c667d4377f2337f2cf465Chris Craik virtual void output(int level, uint32_t logFlags = 0) const = 0; 822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik // NOTE: it would be nice to declare constants and overriding the implementation in each op to 842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik // point at the constants, but that seems to require a .cpp file 852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik virtual const char* name() = 0; 862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass StateOp : public DisplayListOp { 892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 9064bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, 91d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 92ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik // default behavior only affects immediate, deferrable state, issue directly to renderer 93ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik applyState(deferStruct.mRenderer, saveCount); 94ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 95ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 96c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik /** 97c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * State operations are applied directly to the renderer, but can cause the deferred drawing op 98c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik * list to flush 99c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik */ 10064bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, 101d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 102ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik applyState(replayStruct.mRenderer, saveCount); 103c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 104c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 1057273daace9303f4662444111c40bb83d3ead4a92Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const = 0; 1062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 1072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawOp : public DisplayListOp { 109527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craikfriend class MergingDrawBatch; 1102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 111d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawOp(const SkPaint* paint) 1122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mPaint(paint), mQuickRejected(false) {} 1132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 11464bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, 115d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 116dd671599bed9d3ca28e2c744e8c224e1e15bc914Chet Haase if (mQuickRejected && CC_LIKELY(useQuickReject)) { 117ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik return; 118c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 119c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 120ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik deferStruct.mDeferredList.addDrawOp(deferStruct.mRenderer, this); 121ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 122ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 12364bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, 124d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 125dd671599bed9d3ca28e2c744e8c224e1e15bc914Chet Haase if (mQuickRejected && CC_LIKELY(useQuickReject)) { 126ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik return; 127c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 128c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 129107843de4507b3511006cb9c77b8d0364374385aTom Hudson applyDraw(replayStruct.mRenderer, replayStruct.mDirty); 130c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 131c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 132107843de4507b3511006cb9c77b8d0364374385aTom Hudson virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0; 1332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 134527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik /** 135527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * Draw multiple instances of an operation, must be overidden for operations that merge 136527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * 137527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * Currently guarantees certain similarities between ops (see MergingDrawBatch::canMergeWith), 138527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * and pure translation transformations. Other guarantees of similarity should be enforced by 139527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * reducing which operations are tagged as mergeable. 140527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik */ 141107843de4507b3511006cb9c77b8d0364374385aTom Hudson virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, 142272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck const std::vector<OpStatePair>& ops, const Rect& bounds) { 143527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik for (unsigned int i = 0; i < ops.size(); i++) { 144c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik renderer.restoreDisplayState(*(ops[i].state), true); 145107843de4507b3511006cb9c77b8d0364374385aTom Hudson ops[i].op->applyDraw(renderer, dirty); 146527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 147527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 148527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 14928ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik /** 150527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * When this method is invoked the state field is initialized to have the 151527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * final rendering state. We can thus use it to process data as it will be 152527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * used at draw time. 153527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * 154527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * Additionally, this method allows subclasses to provide defer-time preferences for batching 155527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * and merging. 156527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik * 15728ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik * if a subclass can set deferInfo.mergeable to true, it should implement multiDraw() 158527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik */ 15964bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 16064bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe const DeferredDisplayState& state) {} 1610f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy 1625e49b307eb99269db2db257760508b8efd7bb97dChris Craik /** 1635e49b307eb99269db2db257760508b8efd7bb97dChris Craik * Query the conservative, local bounds (unmapped) bounds of the op. 1645e49b307eb99269db2db257760508b8efd7bb97dChris Craik * 1655e49b307eb99269db2db257760508b8efd7bb97dChris Craik * returns true if bounds exist 1665e49b307eb99269db2db257760508b8efd7bb97dChris Craik */ 16764bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual bool getLocalBounds(Rect& localBounds) { 168c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik return false; 169c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik } 1702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1712af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik // TODO: better refine localbounds usage 1722af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; } 1732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik bool getQuickRejected() { return mQuickRejected; } 1742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 175c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger virtual bool hasTextShadow() const { 176c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger return false; 177c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger } 178c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger 179527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik inline float strokeWidthOutset() { 180f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik // since anything AA stroke with less than 1.0 pixel width is drawn with an alpha-reduced 181f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik // 1.0 stroke, treat 1.0 as minimum. 182f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik 183f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik // TODO: it would be nice if this could take scale into account, but scale isn't stable 184f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik // since higher levels of the view hierarchy can change scale out from underneath it. 185df72b63928cc1492b72ba9a4e99d5e714f93ccc6Chris Craik return std::max(mPaint->getStrokeWidth(), 1.0f) * 0.5f; 186e7c69c6fe3eac1fb01126ede550e5dc32979804aChris Craik } 187c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 1882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprotected: 18928ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik // Helper method for determining op opaqueness. Assumes op fills its bounds in local 19028ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik // coordinates, and that paint's alpha is used 191c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik inline bool isOpaqueOverBounds(const DeferredDisplayState& state) { 19228ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik // ensure that local bounds cover mapped bounds 19328ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik if (!state.mMatrix.isSimple()) return false; 19428ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik 1952262abbd16e4d6c7c2e40f7d81b02dfe7db846e8Chris Craik if (state.mRoundRectClipState) return false; 1962262abbd16e4d6c7c2e40f7d81b02dfe7db846e8Chris Craik 19728ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik // check state/paint for transparency 198d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (mPaint) { 199c5b5f0556b542a22f01d254e6284f69e9eb23e74Chris Craik if (mPaint->getAlpha() != 0xFF) { 200c5b5f0556b542a22f01d254e6284f69e9eb23e74Chris Craik return false; 201c5b5f0556b542a22f01d254e6284f69e9eb23e74Chris Craik } 202d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (mPaint->getShader() && !mPaint->getShader()->isOpaque()) { 203d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return false; 204d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 2058dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (PaintUtils::isBlendedColorFilter(mPaint->getColorFilter())) { 206d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return false; 207d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 208d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 209d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 210d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (state.mAlpha != 1.0f) return false; 21128ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik 212bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(mPaint); 21328ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik return (mode == SkXfermode::kSrcOver_Mode || 21428ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik mode == SkXfermode::kSrc_Mode); 21528ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik 21628ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik } 21728ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik 21809c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger const SkPaint* mPaint; 2192af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik bool mQuickRejected; 2202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 2212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 2222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawBoundedOp : public DrawOp { 2232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 224d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawBoundedOp(float left, float top, float right, float bottom, const SkPaint* paint) 2252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawOp(paint), mLocalBounds(left, top, right, bottom) {} 2262af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 227d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawBoundedOp(const Rect& localBounds, const SkPaint* paint) 22841541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik : DrawOp(paint), mLocalBounds(localBounds) {} 22941541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik 2305d11676414b3606792e23c269cf75b44faa1a2afChris Craik // Calculates bounds as smallest rect encompassing all points 2315d11676414b3606792e23c269cf75b44faa1a2afChris Craik // NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in 2325d11676414b3606792e23c269cf75b44faa1a2afChris Craik // subclass' constructor) 233d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawBoundedOp(const float* points, int count, const SkPaint* paint) 2345d11676414b3606792e23c269cf75b44faa1a2afChris Craik : DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) { 2355d11676414b3606792e23c269cf75b44faa1a2afChris Craik for (int i = 2; i < count; i += 2) { 236df72b63928cc1492b72ba9a4e99d5e714f93ccc6Chris Craik mLocalBounds.left = std::min(mLocalBounds.left, points[i]); 237df72b63928cc1492b72ba9a4e99d5e714f93ccc6Chris Craik mLocalBounds.right = std::max(mLocalBounds.right, points[i]); 238df72b63928cc1492b72ba9a4e99d5e714f93ccc6Chris Craik mLocalBounds.top = std::min(mLocalBounds.top, points[i + 1]); 239df72b63928cc1492b72ba9a4e99d5e714f93ccc6Chris Craik mLocalBounds.bottom = std::max(mLocalBounds.bottom, points[i + 1]); 2405d11676414b3606792e23c269cf75b44faa1a2afChris Craik } 2415d11676414b3606792e23c269cf75b44faa1a2afChris Craik } 2425d11676414b3606792e23c269cf75b44faa1a2afChris Craik 2435d11676414b3606792e23c269cf75b44faa1a2afChris Craik // default empty constructor for bounds, to be overridden in child constructor body 244d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawBoundedOp(const SkPaint* paint): DrawOp(paint) { } 2452af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 246d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual bool getLocalBounds(Rect& localBounds) override { 2472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik localBounds.set(mLocalBounds); 248bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik PaintUtils::TextShadow textShadow; 249bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik if (PaintUtils::getTextShadow(mPaint, &textShadow)) { 2509b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy Rect shadow(mLocalBounds); 251c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger shadow.translate(textShadow.dx, textShadow.dx); 252c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger shadow.outset(textShadow.radius); 2539b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy localBounds.unionWith(shadow); 2549b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy } 2552af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik return true; 2562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 2572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 2582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprotected: 2592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint 2602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 2612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 2622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik/////////////////////////////////////////////////////////////////////////////// 2632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik// STATE OPERATIONS - these may affect the state of the canvas/renderer, but do 2642af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik// not directly draw or alter output 2652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik/////////////////////////////////////////////////////////////////////////////// 2662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 2672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass SaveOp : public StateOp { 2682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 2692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik SaveOp(int flags) 2702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mFlags(flags) {} 2712af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 27264bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, 273d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 274ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik int newSaveCount = deferStruct.mRenderer.save(mFlags); 275ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik deferStruct.mDeferredList.addSave(deferStruct.mRenderer, this, newSaveCount); 276ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 277ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 278d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 2792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.save(mFlags); 2802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 2812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 282d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 2832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Save flags %x", mFlags); 2842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 2852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 286d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "Save"; } 2872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 288ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik int getFlags() const { return mFlags; } 2892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 2902af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mFlags; 2912af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 2922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 2932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass RestoreToCountOp : public StateOp { 2942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 2952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik RestoreToCountOp(int count) 2962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mCount(count) {} 2972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 29864bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, 299d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 3007273daace9303f4662444111c40bb83d3ead4a92Chris Craik deferStruct.mDeferredList.addRestoreToCount(deferStruct.mRenderer, 3017273daace9303f4662444111c40bb83d3ead4a92Chris Craik this, saveCount + mCount); 302ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik deferStruct.mRenderer.restoreToCount(saveCount + mCount); 303ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 304ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 305d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 3062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.restoreToCount(saveCount + mCount); 3072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 3082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 309d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 3102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Restore to count %d", mCount); 3112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 3122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 313d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "RestoreToCount"; } 3142af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3152af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 3162af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mCount; 3172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 3182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3192af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass SaveLayerOp : public StateOp { 3202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 321d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger SaveLayerOp(float left, float top, float right, float bottom, int alpha, int flags) 3223f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik : mArea(left, top, right, bottom) 3233f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik , mPaint(&mCachedPaint) 3243f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik , mFlags(flags) 325d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mConvexMask(nullptr) { 326d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger mCachedPaint.setAlpha(alpha); 327d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger } 328d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger 329d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger SaveLayerOp(float left, float top, float right, float bottom, const SkPaint* paint, int flags) 3303f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik : mArea(left, top, right, bottom) 3313f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik , mPaint(paint) 3323f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik , mFlags(flags) 333d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mConvexMask(nullptr) 3343f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik {} 3352af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 33664bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, 337d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 338ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik // NOTE: don't bother with actual saveLayer, instead issuing it at flush time 339d90144db52c7297879b950cbbc85137ed123ab5bChris Craik int newSaveCount = deferStruct.mRenderer.getSaveCount(); 340ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik deferStruct.mDeferredList.addSaveLayer(deferStruct.mRenderer, this, newSaveCount); 341d90144db52c7297879b950cbbc85137ed123ab5bChris Craik 342d90144db52c7297879b950cbbc85137ed123ab5bChris Craik // NOTE: don't issue full saveLayer, since that has side effects/is costly. instead just 343d90144db52c7297879b950cbbc85137ed123ab5bChris Craik // setup the snapshot for deferral, and re-issue the op at flush time 344d90144db52c7297879b950cbbc85137ed123ab5bChris Craik deferStruct.mRenderer.saveLayerDeferred(mArea.left, mArea.top, mArea.right, mArea.bottom, 345d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger mPaint, mFlags); 3462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 3472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 348d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 3493f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, 3503f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik mPaint, mFlags, mConvexMask); 3512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 3522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 353d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 354ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik OP_LOG("SaveLayer%s of area " RECT_STRING, 355ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik (isSaveLayerAlpha() ? "Alpha" : ""),RECT_ARGS(mArea)); 3562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 3572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 358d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { 359d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik return isSaveLayerAlpha() ? "SaveLayerAlpha" : "SaveLayer"; 360d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik } 361ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 362ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik int getFlags() { return mFlags; } 363c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 3643f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik // Called to make SaveLayerOp clip to the provided mask when drawing back/restored 3653f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik void setMask(const SkPath* convexMask) { 3663f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik mConvexMask = convexMask; 3673f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik } 3683f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 3692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 370d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger bool isSaveLayerAlpha() const { 371bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(mPaint); 372bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik int alpha = PaintUtils::getAlphaDirect(mPaint); 373d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger return alpha < 255 && mode == SkXfermode::kSrcOver_Mode; 374ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 375ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 3762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik Rect mArea; 377d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger const SkPaint* mPaint; 378d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger SkPaint mCachedPaint; 3792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mFlags; 3803f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 3813f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik // Convex path, points at data in RenderNode, valid for the duration of the frame only 3823f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik // Only used for masking the SaveLayer which wraps projected RenderNodes 3833f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik const SkPath* mConvexMask; 3842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 3852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass TranslateOp : public StateOp { 3872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 3882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik TranslateOp(float dx, float dy) 3892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mDx(dx), mDy(dy) {} 3902af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 391d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 3922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.translate(mDx, mDy); 3932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 3942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 395d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 3962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Translate by %f %f", mDx, mDy); 3972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 3982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 399d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "Translate"; } 4002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 4022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mDx; 4032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mDy; 4042af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 4052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass RotateOp : public StateOp { 4072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 4082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik RotateOp(float degrees) 4092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mDegrees(degrees) {} 4102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 411d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 4122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.rotate(mDegrees); 4132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4142af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 415d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 4162af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Rotate by %f degrees", mDegrees); 4172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 419d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "Rotate"; } 4202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 4222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mDegrees; 4232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 4242af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass ScaleOp : public StateOp { 4262af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 4272af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik ScaleOp(float sx, float sy) 4282af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mSx(sx), mSy(sy) {} 4292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 430d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 4312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.scale(mSx, mSy); 4322af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 434d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 4352af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Scale by %f %f", mSx, mSy); 4362af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 438d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "Scale"; } 4392af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4402af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 4412af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mSx; 4422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mSy; 4432af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 4442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4452af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass SkewOp : public StateOp { 4462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 4472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik SkewOp(float sx, float sy) 4482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mSx(sx), mSy(sy) {} 4492af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 450d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 4512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.skew(mSx, mSy); 4522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 454d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 4552af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Skew by %f %f", mSx, mSy); 4562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 458d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "Skew"; } 4592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 4612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mSx; 4622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mSy; 4632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 4642af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass SetMatrixOp : public StateOp { 4662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 467139088228faa7f3c446af7387e017933998a5570Derek Sollenberger SetMatrixOp(const SkMatrix& matrix) 4682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mMatrix(matrix) {} 4692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 470d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 4716daa13c5fa7577fa1d8371deca446f6ca911f38fChris Craik // Setting a matrix on a Canvas isn't equivalent to setting a total matrix on the scene. 4726daa13c5fa7577fa1d8371deca446f6ca911f38fChris Craik // Set a canvas-relative matrix on the renderer instead. 4736daa13c5fa7577fa1d8371deca446f6ca911f38fChris Craik renderer.setLocalMatrix(mMatrix); 4742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4752af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 476d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 477139088228faa7f3c446af7387e017933998a5570Derek Sollenberger if (mMatrix.isIdentity()) { 4784e7b772b733593fbe25c733e95b8dcea293234b6Romain Guy OP_LOGS("SetMatrix (reset)"); 479139088228faa7f3c446af7387e017933998a5570Derek Sollenberger } else { 480139088228faa7f3c446af7387e017933998a5570Derek Sollenberger OP_LOG("SetMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(&mMatrix)); 4814e7b772b733593fbe25c733e95b8dcea293234b6Romain Guy } 4822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 484d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "SetMatrix"; } 4852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 487139088228faa7f3c446af7387e017933998a5570Derek Sollenberger const SkMatrix mMatrix; 4882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 4892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4902af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass ConcatMatrixOp : public StateOp { 4912af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 492139088228faa7f3c446af7387e017933998a5570Derek Sollenberger ConcatMatrixOp(const SkMatrix& matrix) 4932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : mMatrix(matrix) {} 4942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 495d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 4962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.concatMatrix(mMatrix); 4972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 499d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 500139088228faa7f3c446af7387e017933998a5570Derek Sollenberger OP_LOG("ConcatMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(&mMatrix)); 5012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 503d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "ConcatMatrix"; } 5042af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 5052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 506139088228faa7f3c446af7387e017933998a5570Derek Sollenberger const SkMatrix mMatrix; 5072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 5082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 509ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikclass ClipOp : public StateOp { 510ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikpublic: 511ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik ClipOp(SkRegion::Op op) : mOp(op) {} 512ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 51364bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, 514d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 515ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik // NOTE: must defer op BEFORE applying state, since it may read clip 516ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik deferStruct.mDeferredList.addClip(deferStruct.mRenderer, this); 517ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 518ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik // TODO: Can we avoid applying complex clips at defer time? 519ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik applyState(deferStruct.mRenderer, saveCount); 520ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 521ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 522ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik bool canCauseComplexClip() { 523ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik return ((mOp != SkRegion::kIntersect_Op) && (mOp != SkRegion::kReplace_Op)) || !isRect(); 524ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 525ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 526ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikprotected: 527ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik virtual bool isRect() { return false; } 528ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 529ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik SkRegion::Op mOp; 530ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik}; 531ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik 532ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikclass ClipRectOp : public ClipOp { 5332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 5342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op) 535ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik : ClipOp(op), mArea(left, top, right, bottom) {} 5362af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 537d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 5382af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp); 5392af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5402af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 541d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 5422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea)); 5432af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 545d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "ClipRect"; } 5462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 547ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikprotected: 548d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual bool isRect() override { return true; } 549b98a016c6769b9e80d392df22fe77a2fca048d9fChris Craik 5502af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 5512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik Rect mArea; 5522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 5532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 554ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikclass ClipPathOp : public ClipOp { 5552af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 556d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik ClipPathOp(const SkPath* path, SkRegion::Op op) 557ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik : ClipOp(op), mPath(path) {} 5582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 559d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 5602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.clipPath(mPath, mOp); 5612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 563d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 5642af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik SkRect bounds = mPath->getBounds(); 5652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("ClipPath bounds " RECT_STRING, 5662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); 5672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 569d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "ClipPath"; } 5702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 5712af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 572d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkPath* mPath; 5732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 5742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 575ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craikclass ClipRegionOp : public ClipOp { 5762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 577d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik ClipRegionOp(const SkRegion* region, SkRegion::Op op) 578ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik : ClipOp(op), mRegion(region) {} 5792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 580d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override { 5812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.clipRegion(mRegion, mOp); 5822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 584d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 5852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik SkIRect bounds = mRegion->getBounds(); 5862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("ClipRegion bounds %d %d %d %d", 5872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); 5882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 590d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "ClipRegion"; } 5912af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 5922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 593d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkRegion* mRegion; 5942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 5952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 5962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik/////////////////////////////////////////////////////////////////////////////// 5972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik// DRAW OPERATIONS - these are operations that can draw to the canvas's device 5982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik/////////////////////////////////////////////////////////////////////////////// 5992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 6002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawBitmapOp : public DrawBoundedOp { 6012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 602796475006f5d670e8383a2050f11719522437a43Chris Craik DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint) 603796475006f5d670e8383a2050f11719522437a43Chris Craik : DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint) 604796475006f5d670e8383a2050f11719522437a43Chris Craik , mBitmap(bitmap) 605d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mEntryValid(false), mEntry(nullptr) { 6063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 6072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 608d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 609107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawBitmap(mBitmap, mPaint); 6102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 6112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 612ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) { 613ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck if (!mEntryValid) { 614ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mEntryValid = true; 615ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap); 61655b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy } 61755b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy return mEntry; 61855b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy } 61955b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy 620527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik#define SET_TEXTURE(ptr, posRect, offsetRect, texCoordsRect, xDim, yDim) \ 621527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik TextureVertex::set(ptr++, posRect.xDim - offsetRect.left, posRect.yDim - offsetRect.top, \ 622527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik texCoordsRect.xDim, texCoordsRect.yDim) 623527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 62403c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy /** 62503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy * This multi-draw operation builds a mesh on the stack by generating a quad 62603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy * for each bitmap in the batch. This method is also responsible for dirtying 62703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy * the current layer, if any. 62803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy */ 62964bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, 630272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck const std::vector<OpStatePair>& ops, const Rect& bounds) override { 631c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik const DeferredDisplayState& firstState = *(ops[0].state); 632c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik renderer.restoreDisplayState(firstState, true); // restore all but the clip 633c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik 634527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik TextureVertex vertices[6 * ops.size()]; 635527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik TextureVertex* vertex = &vertices[0]; 636527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 63703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy const bool hasLayer = renderer.hasLayer(); 638996fe656340ede058a6f0e6b18f9ec525ddb4e27Chris Craik bool pureTranslate = true; 6392db5e993b626794eb07a0ff354269f9a77da81b3Romain Guy 6403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy // TODO: manually handle rect clip for bitmaps by adjusting texCoords per op, 6413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy // and allowing them to be merged in getBatchId() 642527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik for (unsigned int i = 0; i < ops.size(); i++) { 643c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik const DeferredDisplayState& state = *(ops[i].state); 644c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik const Rect& opBounds = state.mBounds; 6452db5e993b626794eb07a0ff354269f9a77da81b3Romain Guy // When we reach multiDraw(), the matrix can be either 6462db5e993b626794eb07a0ff354269f9a77da81b3Romain Guy // pureTranslate or simple (translate and/or scale). 6472db5e993b626794eb07a0ff354269f9a77da81b3Romain Guy // If the matrix is not pureTranslate, then we have a scale 648996fe656340ede058a6f0e6b18f9ec525ddb4e27Chris Craik pureTranslate &= state.mMatrix.isPureTranslate(); 6493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 6503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy Rect texCoords(0, 0, 1, 1); 651ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck ((DrawBitmapOp*) ops[i].op)->uvMap(renderer, texCoords); 6523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 653527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top); 654527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top); 655527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom); 656527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 657527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom); 658527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top); 659527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, bottom); 66003c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 66103c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy if (hasLayer) { 662c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik renderer.dirtyLayer(opBounds.left, opBounds.top, opBounds.right, opBounds.bottom); 66303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 664527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 665527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 666107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0], 667996fe656340ede058a6f0e6b18f9ec525ddb4e27Chris Craik pureTranslate, bounds, mPaint); 668527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 669527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 670d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 6710519c810a56bded1284fcb2ae40f438878c6585fChris Craik OP_LOG("Draw bitmap %p of size %dx%d%s", 6720519c810a56bded1284fcb2ae40f438878c6585fChris Craik mBitmap, mBitmap->width(), mBitmap->height(), 673dad7d84c04c5954b63ea8bb58c52b2291f44b4dfJohn Reck mEntry ? " using AssetAtlas" : ""); 6742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 6752af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 676d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawBitmap"; } 677527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 67864bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 679d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 68028ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap; 681ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck deferInfo.mergeId = getAtlasEntry(renderer) ? 682d965bc5823d878a3fd056b8a95fb4eb578ed3fe4Chris Craik (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap; 6832db5e993b626794eb07a0ff354269f9a77da81b3Romain Guy 684d965bc5823d878a3fd056b8a95fb4eb578ed3fe4Chris Craik // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation 68528ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in 68628ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik // MergingDrawBatch::canMergeWith() 68728ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik // TODO: support clipped bitmaps by handling them in SET_TEXTURE 688d965bc5823d878a3fd056b8a95fb4eb578ed3fe4Chris Craik deferInfo.mergeable = state.mMatrix.isSimple() && state.mMatrix.positiveScale() && 689d965bc5823d878a3fd056b8a95fb4eb578ed3fe4Chris Craik !state.mClipSideFlags && 690bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik PaintUtils::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode && 6911103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed (mBitmap->colorType() != kAlpha_8_SkColorType); 692c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 6932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 694ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck void uvMap(OpenGLRenderer& renderer, Rect& texCoords) { 695ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck if (getAtlasEntry(renderer)) { 696ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mEntry->uvMapper.map(texCoords); 697ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck } 698ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck } 699ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck 700527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik const SkBitmap* bitmap() { return mBitmap; } 7012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprotected: 702d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkBitmap* mBitmap; 703ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck bool mEntryValid; 70455b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy AssetAtlas::Entry* mEntry; 7052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 7062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 7072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawBitmapRectOp : public DrawBoundedOp { 7082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 709d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawBitmapRectOp(const SkBitmap* bitmap, 710d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float srcLeft, float srcTop, float srcRight, float srcBottom, 711d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) 7122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint), 7132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {} 7142af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 715d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 71614100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik renderer.drawBitmap(mBitmap, mSrc, mLocalBounds, mPaint); 7172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 7182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 719d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 720ce444ca4006cfe0e2151d858da732fc413a716bdJohn Reck OP_LOG("Draw bitmap %p src=" RECT_STRING ", dst=" RECT_STRING, 7212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds)); 7222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 7232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 724d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawBitmapRect"; } 725527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 72664bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 727d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 72828ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap; 729c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 7302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 7312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 732d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkBitmap* mBitmap; 7332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik Rect mSrc; 7342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 7352af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 7365d11676414b3606792e23c269cf75b44faa1a2afChris Craikclass DrawBitmapMeshOp : public DrawBoundedOp { 7372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 738d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawBitmapMeshOp(const SkBitmap* bitmap, int meshWidth, int meshHeight, 739d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const float* vertices, const int* colors, const SkPaint* paint) 7405d11676414b3606792e23c269cf75b44faa1a2afChris Craik : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint), 7415d11676414b3606792e23c269cf75b44faa1a2afChris Craik mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight), 7422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mVertices(vertices), mColors(colors) {} 7432af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 744d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 745107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight, 74609c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger mVertices, mColors, mPaint); 7472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 7482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 749d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 7502af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight); 7512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 7522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 753d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawBitmapMesh"; } 754527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 75564bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 756d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 75728ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap; 758c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 7592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 7602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 761d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkBitmap* mBitmap; 7622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mMeshWidth; 7632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mMeshHeight; 764d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const float* mVertices; 765d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const int* mColors; 7662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 7672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 7682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawPatchOp : public DrawBoundedOp { 7692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 770d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawPatchOp(const SkBitmap* bitmap, const Res_png_9patch* patch, 771d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float left, float top, float right, float bottom, const SkPaint* paint) 77203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy : DrawBoundedOp(left, top, right, bottom, paint), 773d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(nullptr), 774d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mEntryValid(false), mEntry(nullptr) { 7753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy }; 7762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 777ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) { 778ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck if (!mEntryValid) { 779ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mEntryValid = true; 780ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap); 78155b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy } 78255b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy return mEntry; 78355b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy } 78455b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy 78503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy const Patch* getMesh(OpenGLRenderer& renderer) { 7864c2547fa9244e78115cde0a259291053108c3dc7Romain Guy if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) { 7874c2547fa9244e78115cde0a259291053108c3dc7Romain Guy PatchCache& cache = renderer.getCaches().patchCache; 788ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mMesh = cache.get(getAtlasEntry(renderer), mBitmap->width(), mBitmap->height(), 78903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy mLocalBounds.getWidth(), mLocalBounds.getHeight(), mPatch); 7904c2547fa9244e78115cde0a259291053108c3dc7Romain Guy mGenerationId = cache.getGenerationId(); 7914c2547fa9244e78115cde0a259291053108c3dc7Romain Guy } 79203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy return mMesh; 79303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 79403c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 79503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy /** 79603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy * This multi-draw operation builds an indexed mesh on the stack by copying 79703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy * and transforming the vertices of each 9-patch in the batch. This method 79803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy * is also responsible for dirtying the current layer, if any. 79903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy */ 80064bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, 801272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck const std::vector<OpStatePair>& ops, const Rect& bounds) override { 802c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik const DeferredDisplayState& firstState = *(ops[0].state); 803c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik renderer.restoreDisplayState(firstState, true); // restore all but the clip 80403c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 80503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // Batches will usually contain a small number of items so it's 80603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // worth performing a first iteration to count the exact number 80703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // of vertices we need in the new mesh 80803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy uint32_t totalVertices = 0; 80903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy for (unsigned int i = 0; i < ops.size(); i++) { 810c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik totalVertices += ((DrawPatchOp*) ops[i].op)->getMesh(renderer)->verticesCount; 81103c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 81203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 81303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy const bool hasLayer = renderer.hasLayer(); 81403c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 81503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy uint32_t indexCount = 0; 81603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 81703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy TextureVertex vertices[totalVertices]; 81803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy TextureVertex* vertex = &vertices[0]; 81903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 82003c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // Create a mesh that contains the transformed vertices for all the 82103c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // 9-patch objects that are part of the batch. Note that onDefer() 82203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // enforces ops drawn by this function to have a pure translate or 82303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // identity matrix 82403c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy for (unsigned int i = 0; i < ops.size(); i++) { 825c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik DrawPatchOp* patchOp = (DrawPatchOp*) ops[i].op; 826c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik const DeferredDisplayState* state = ops[i].state; 82703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy const Patch* opMesh = patchOp->getMesh(renderer); 82803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy uint32_t vertexCount = opMesh->verticesCount; 82903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy if (vertexCount == 0) continue; 83003c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 83103c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // We use the bounds to know where to translate our vertices 83203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // Using patchOp->state.mBounds wouldn't work because these 83303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // bounds are clipped 834c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik const float tx = (int) floorf(state->mMatrix.getTranslateX() + 83503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy patchOp->mLocalBounds.left + 0.5f); 836c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik const float ty = (int) floorf(state->mMatrix.getTranslateY() + 83703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy patchOp->mLocalBounds.top + 0.5f); 83803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 83903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // Copy & transform all the vertices for the current operation 84051d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik TextureVertex* opVertices = opMesh->vertices.get(); 84103c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy for (uint32_t j = 0; j < vertexCount; j++, opVertices++) { 84203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy TextureVertex::set(vertex++, 8433380cfdc77100e87aa8390386ccf390834dea171Romain Guy opVertices->x + tx, opVertices->y + ty, 8443380cfdc77100e87aa8390386ccf390834dea171Romain Guy opVertices->u, opVertices->v); 84503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 84603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 84703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // Dirty the current layer if possible. When the 9-patch does not 84803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // contain empty quads we can take a shortcut and simply set the 84903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy // dirty rect to the object's bounds. 85003c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy if (hasLayer) { 85103c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy if (!opMesh->hasEmptyQuads) { 85203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy renderer.dirtyLayer(tx, ty, 85303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy tx + patchOp->mLocalBounds.getWidth(), 85403c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy ty + patchOp->mLocalBounds.getHeight()); 85503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } else { 85603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy const size_t count = opMesh->quads.size(); 85703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy for (size_t i = 0; i < count; i++) { 85803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy const Rect& quadBounds = opMesh->quads[i]; 85903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy const float x = tx + quadBounds.left; 86003c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy const float y = ty + quadBounds.top; 86103c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy renderer.dirtyLayer(x, y, 86203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy x + quadBounds.getWidth(), y + quadBounds.getHeight()); 86303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 86403c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 86503c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 86603c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 86703c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy indexCount += opMesh->indexCount; 86803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 86903c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 87059cf734f9ee8fa0154d199f0f36779a6ffe0dfb5Yohann Roussel renderer.drawPatches(mBitmap, getAtlasEntry(renderer), 87109c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger &vertices[0], indexCount, mPaint); 87203c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy } 87303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 874d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 8754c2547fa9244e78115cde0a259291053108c3dc7Romain Guy // We're not calling the public variant of drawPatch() here 8764c2547fa9244e78115cde0a259291053108c3dc7Romain Guy // This method won't perform the quickReject() since we've already done it at this point 87759cf734f9ee8fa0154d199f0f36779a6ffe0dfb5Yohann Roussel renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(renderer), 87803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom, 87909c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger mPaint); 8802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 8812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 882d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 883dad7d84c04c5954b63ea8bb58c52b2291f44b4dfJohn Reck OP_LOG("Draw patch " RECT_STRING "%s", RECT_ARGS(mLocalBounds), 884dad7d84c04c5954b63ea8bb58c52b2291f44b4dfJohn Reck mEntry ? " with AssetAtlas" : ""); 8852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 8862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 887d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawPatch"; } 888527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 88964bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 890d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 89128ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch; 892ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck deferInfo.mergeId = getAtlasEntry(renderer) ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap; 89303c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy deferInfo.mergeable = state.mMatrix.isPureTranslate() && 894bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik PaintUtils::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode; 895c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mBitmap->isOpaque(); 896c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 8972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 8982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 899d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkBitmap* mBitmap; 900d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const Res_png_9patch* mPatch; 9014c2547fa9244e78115cde0a259291053108c3dc7Romain Guy 9024c2547fa9244e78115cde0a259291053108c3dc7Romain Guy uint32_t mGenerationId; 9034c2547fa9244e78115cde0a259291053108c3dc7Romain Guy const Patch* mMesh; 90403c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy 905ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck bool mEntryValid; 9063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy AssetAtlas::Entry* mEntry; 9072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 9082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 9092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawColorOp : public DrawOp { 9102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 9112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik DrawColorOp(int color, SkXfermode::Mode mode) 912d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : DrawOp(nullptr), mColor(color), mMode(mode) {}; 9132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 914d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 915107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawColor(mColor, mMode); 9162af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 9172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 918d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 9192af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw color %#x, mode %d", mColor, mMode); 9202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 9212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 922d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawColor"; } 9232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 9242af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 9252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mColor; 9262af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik SkXfermode::Mode mMode; 9272af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 9282af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 9292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawStrokableOp : public DrawBoundedOp { 9302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 931d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawStrokableOp(float left, float top, float right, float bottom, const SkPaint* paint) 9322af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawBoundedOp(left, top, right, bottom, paint) {}; 933947eabf42d835d0dfb0daa2fe6d869139c7000d6Chris Craik DrawStrokableOp(const Rect& localBounds, const SkPaint* paint) 934947eabf42d835d0dfb0daa2fe6d869139c7000d6Chris Craik : DrawBoundedOp(localBounds, paint) {}; 9352af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 936d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual bool getLocalBounds(Rect& localBounds) override { 937c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik localBounds.set(mLocalBounds); 9382af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) { 939c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik localBounds.outset(strokeWidthOutset()); 9402af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 9412af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik return true; 9422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 943c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 94464bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 945d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 946c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik if (mPaint->getPathEffect()) { 94728ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture; 948527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } else { 94928ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = mPaint->isAntiAlias() ? 950527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik DeferredDisplayList::kOpBatch_AlphaVertices : 951527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik DeferredDisplayList::kOpBatch_Vertices; 952c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 953c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 9542af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 9552af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 9562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawRectOp : public DrawStrokableOp { 9572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 958d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawRectOp(float left, float top, float right, float bottom, const SkPaint* paint) 9592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawStrokableOp(left, top, right, bottom, paint) {} 9602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 961d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 962107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawRect(mLocalBounds.left, mLocalBounds.top, 96309c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger mLocalBounds.right, mLocalBounds.bottom, mPaint); 9642af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 9652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 966d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 967ce444ca4006cfe0e2151d858da732fc413a716bdJohn Reck OP_LOG("Draw Rect " RECT_STRING, RECT_ARGS(mLocalBounds)); 9682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 9692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 970c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 971d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 972c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik DrawStrokableOp::onDefer(renderer, deferInfo, state); 973c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && 97428ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik mPaint->getStyle() == SkPaint::kFill_Style; 97528ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik } 97628ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik 977d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawRect"; } 9782af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 9792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 9805d11676414b3606792e23c269cf75b44faa1a2afChris Craikclass DrawRectsOp : public DrawBoundedOp { 9812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 982d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawRectsOp(const float* rects, int count, const SkPaint* paint) 9835d11676414b3606792e23c269cf75b44faa1a2afChris Craik : DrawBoundedOp(rects, count, paint), 9845d11676414b3606792e23c269cf75b44faa1a2afChris Craik mRects(rects), mCount(count) {} 9852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 986d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 987107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawRects(mRects, mCount, mPaint); 9882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 9892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 990d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 9912af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw Rects count %d", mCount); 9922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 9932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 994d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawRects"; } 9952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 99664bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 997d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 99828ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = DeferredDisplayList::kOpBatch_Vertices; 999c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 1000c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 10012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 10022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik const float* mRects; 10032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mCount; 10042af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 10052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 10062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawRoundRectOp : public DrawStrokableOp { 10072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 10082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik DrawRoundRectOp(float left, float top, float right, float bottom, 1009d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float rx, float ry, const SkPaint* paint) 10102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {} 10112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1012d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1013107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top, 101409c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, mPaint); 10152af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 10162af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1017d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 1018ce444ca4006cfe0e2151d858da732fc413a716bdJohn Reck OP_LOG("Draw RoundRect " RECT_STRING ", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy); 10192af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 10202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 102105f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 1022d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 102305f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik DrawStrokableOp::onDefer(renderer, deferInfo, state); 102405f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik if (!mPaint->getPathEffect()) { 10256ac174b97246ed40fe780b29561603b61770fa17Chris Craik renderer.getCaches().tessellationCache.precacheRoundRect(state.mMatrix, *mPaint, 10266ac174b97246ed40fe780b29561603b61770fa17Chris Craik mLocalBounds.getWidth(), mLocalBounds.getHeight(), mRx, mRy); 102705f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik } 102805f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik } 102905f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik 1030d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawRoundRect"; } 10312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 10322af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 10332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mRx; 10342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mRy; 10352af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 10362af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1037072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggiclass DrawRoundRectPropsOp : public DrawOp { 1038072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggipublic: 1039072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi DrawRoundRectPropsOp(float* left, float* top, float* right, float* bottom, 1040072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi float *rx, float *ry, const SkPaint* paint) 1041072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi : DrawOp(paint), mLeft(left), mTop(top), mRight(right), mBottom(bottom), 1042072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi mRx(rx), mRy(ry) {} 1043072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi 1044d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1045107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom, 104609c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger *mRx, *mRy, mPaint); 1047072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi } 1048072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi 1049d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 1050072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi OP_LOG("Draw RoundRect Props " RECT_STRING ", rx %f, ry %f", 1051072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi *mLeft, *mTop, *mRight, *mBottom, *mRx, *mRy); 1052072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi } 1053072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi 1054d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawRoundRectProps"; } 1055072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi 1056072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggiprivate: 1057072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi float* mLeft; 1058072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi float* mTop; 1059072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi float* mRight; 1060072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi float* mBottom; 1061072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi float* mRx; 1062072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi float* mRy; 1063072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi}; 1064072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi 10652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawCircleOp : public DrawStrokableOp { 10662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 1067d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawCircleOp(float x, float y, float radius, const SkPaint* paint) 10682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint), 10692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mX(x), mY(y), mRadius(radius) {} 10702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1071d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1072107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawCircle(mX, mY, mRadius, mPaint); 10732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 10742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1075d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 10762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius); 10772af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 10782af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1079d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawCircle"; } 10802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 10812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 10822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mX; 10832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mY; 10842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mRadius; 10852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 10862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 108752244fff29042926e21fa897ef5ab11148e35299John Reckclass DrawCirclePropsOp : public DrawOp { 108852244fff29042926e21fa897ef5ab11148e35299John Reckpublic: 108952244fff29042926e21fa897ef5ab11148e35299John Reck DrawCirclePropsOp(float* x, float* y, float* radius, const SkPaint* paint) 109052244fff29042926e21fa897ef5ab11148e35299John Reck : DrawOp(paint), mX(x), mY(y), mRadius(radius) {} 109152244fff29042926e21fa897ef5ab11148e35299John Reck 1092d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1093107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawCircle(*mX, *mY, *mRadius, mPaint); 109452244fff29042926e21fa897ef5ab11148e35299John Reck } 109552244fff29042926e21fa897ef5ab11148e35299John Reck 1096d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 109752244fff29042926e21fa897ef5ab11148e35299John Reck OP_LOG("Draw Circle Props x %p, y %p, r %p", mX, mY, mRadius); 109852244fff29042926e21fa897ef5ab11148e35299John Reck } 109952244fff29042926e21fa897ef5ab11148e35299John Reck 1100d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawCircleProps"; } 110152244fff29042926e21fa897ef5ab11148e35299John Reck 110252244fff29042926e21fa897ef5ab11148e35299John Reckprivate: 110352244fff29042926e21fa897ef5ab11148e35299John Reck float* mX; 110452244fff29042926e21fa897ef5ab11148e35299John Reck float* mY; 110552244fff29042926e21fa897ef5ab11148e35299John Reck float* mRadius; 110652244fff29042926e21fa897ef5ab11148e35299John Reck}; 110752244fff29042926e21fa897ef5ab11148e35299John Reck 11082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawOvalOp : public DrawStrokableOp { 11092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 1110d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawOvalOp(float left, float top, float right, float bottom, const SkPaint* paint) 11112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawStrokableOp(left, top, right, bottom, paint) {} 11122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1113d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1114107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawOval(mLocalBounds.left, mLocalBounds.top, 111509c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger mLocalBounds.right, mLocalBounds.bottom, mPaint); 11162af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1118d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 1119ce444ca4006cfe0e2151d858da732fc413a716bdJohn Reck OP_LOG("Draw Oval " RECT_STRING, RECT_ARGS(mLocalBounds)); 11202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1122d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawOval"; } 11232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 11242af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 11252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawArcOp : public DrawStrokableOp { 11262af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 11272af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik DrawArcOp(float left, float top, float right, float bottom, 1128d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) 11292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawStrokableOp(left, top, right, bottom, paint), 11302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {} 11312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1132d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1133107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawArc(mLocalBounds.left, mLocalBounds.top, 11342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mLocalBounds.right, mLocalBounds.bottom, 113509c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger mStartAngle, mSweepAngle, mUseCenter, mPaint); 11362af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1138d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 1139ce444ca4006cfe0e2151d858da732fc413a716bdJohn Reck OP_LOG("Draw Arc " RECT_STRING ", start %f, sweep %f, useCenter %d", 11402af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter); 11412af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1143d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawArc"; } 11442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 11452af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 11462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mStartAngle; 11472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mSweepAngle; 11482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik bool mUseCenter; 11492af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 11502af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 11512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawPathOp : public DrawBoundedOp { 11522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 1153d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawPathOp(const SkPath* path, const SkPaint* paint) 11542af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawBoundedOp(paint), mPath(path) { 11552af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float left, top, offset; 11562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik uint32_t width, height; 1157ca89e2a68703bd428e8b66547d033a6ed35b3595Romain Guy PathCache::computePathBounds(path, paint, left, top, offset, width, height); 11582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik left -= offset; 11592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik top -= offset; 11602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mLocalBounds.set(left, top, left + width, top + height); 11612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1163d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1164107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawPath(mPath, mPaint); 11652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1167c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 1168d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 116909c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger renderer.getCaches().pathCache.precache(mPath, mPaint); 1170527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 117128ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture; 1172ca89e2a68703bd428e8b66547d033a6ed35b3595Romain Guy } 1173ca89e2a68703bd428e8b66547d033a6ed35b3595Romain Guy 1174d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 1175ce444ca4006cfe0e2151d858da732fc413a716bdJohn Reck OP_LOG("Draw Path %p in " RECT_STRING, mPath, RECT_ARGS(mLocalBounds)); 11762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11772af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1178d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawPath"; } 11792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 11802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 1181d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkPath* mPath; 11822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 11832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1184c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikclass DrawLinesOp : public DrawBoundedOp { 11852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 1186d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawLinesOp(const float* points, int count, const SkPaint* paint) 11875d11676414b3606792e23c269cf75b44faa1a2afChris Craik : DrawBoundedOp(points, count, paint), 11885d11676414b3606792e23c269cf75b44faa1a2afChris Craik mPoints(points), mCount(count) { 1189c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik mLocalBounds.outset(strokeWidthOutset()); 11902af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11912af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1192d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1193107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawLines(mPoints, mCount, mPaint); 11942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1196d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 11972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw Lines count %d", mCount); 11982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 11992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1200d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawLines"; } 12012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 120264bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 1203d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 120428ce94a4ffc7576f40776d212f1ada79fafaa061Chris Craik deferInfo.batchId = mPaint->isAntiAlias() ? 1205c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DeferredDisplayList::kOpBatch_AlphaVertices : 1206c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DeferredDisplayList::kOpBatch_Vertices; 1207c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 1208c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 12092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprotected: 1210d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const float* mPoints; 12112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mCount; 12122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 12132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 12142af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawPointsOp : public DrawLinesOp { 12152af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 1216d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawPointsOp(const float* points, int count, const SkPaint* paint) 12172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawLinesOp(points, count, paint) {} 12182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1219d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1220107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawPoints(mPoints, mCount, mPaint); 12212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 12222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1223d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 12242af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw Points count %d", mCount); 12252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 12262af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1227d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawPoints"; } 12282af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 12292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 12302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawSomeTextOp : public DrawOp { 12312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 1232d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik DrawSomeTextOp(const char* text, int bytesCount, int count, const SkPaint* paint) 12332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {}; 12342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1235d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 12362af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw some text, %d bytes", mBytesCount); 12372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 1238c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 1239d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual bool hasTextShadow() const override { 1240bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik return PaintUtils::hasTextShadow(mPaint); 1241c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger } 1242c29a0a4664a4b9871fadd668b632469a0db240b9Derek Sollenberger 1243c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 1244d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 1245c08820f587ad94698691a6657e87712de07e484cChris Craik FontRenderer& fontRenderer = renderer.getCaches().fontRenderer.getFontRenderer(); 124609c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger fontRenderer.precache(mPaint, mText, mCount, SkMatrix::I()); 12470f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy 124898d608dba6a0b3c15fb08f1fa2c8b9d170124c7cChris Craik deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ? 1249c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DeferredDisplayList::kOpBatch_Text : 1250c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik DeferredDisplayList::kOpBatch_ColorText; 1251c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 1252527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 12532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprotected: 12542af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik const char* mText; 12552af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mBytesCount; 12562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mCount; 12572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 12582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 12592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawTextOnPathOp : public DrawSomeTextOp { 12602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 12612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik DrawTextOnPathOp(const char* text, int bytesCount, int count, 1262d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) 12632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawSomeTextOp(text, bytesCount, count, paint), 12642af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mPath(path), mHOffset(hOffset), mVOffset(vOffset) { 12652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik /* TODO: inherit from DrawBounded and init mLocalBounds */ 12662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 12672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1268d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1269107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath, 127009c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger mHOffset, mVOffset, mPaint); 12712af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 12722af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1273d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawTextOnPath"; } 12742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 12752af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 1276d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const SkPath* mPath; 12772af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mHOffset; 12782af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mVOffset; 12792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 12802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 12812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawPosTextOp : public DrawSomeTextOp { 12822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 12832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik DrawPosTextOp(const char* text, int bytesCount, int count, 1284d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const float* positions, const SkPaint* paint) 12852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) { 12862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik /* TODO: inherit from DrawBounded and init mLocalBounds */ 12872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 12882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1289d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 1290107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawPosText(mText, mBytesCount, mCount, mPositions, mPaint); 12912af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 12922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1293d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawPosText"; } 12942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 12952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 12962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik const float* mPositions; 12972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 12982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1299947eabf42d835d0dfb0daa2fe6d869139c7000d6Chris Craikclass DrawTextOp : public DrawStrokableOp { 13002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 13012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik DrawTextOp(const char* text, int bytesCount, int count, float x, float y, 1302d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds) 1303947eabf42d835d0dfb0daa2fe6d869139c7000d6Chris Craik : DrawStrokableOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count), 130441541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) { 130559744b79ec302000802cd56d30a1bf70f0183c80Chris Craik mPrecacheTransform = SkMatrix::InvalidMatrix(); 13062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 13072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1308c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 1309d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 1310c08820f587ad94698691a6657e87712de07e484cChris Craik FontRenderer& fontRenderer = renderer.getCaches().fontRenderer.getFontRenderer(); 131159744b79ec302000802cd56d30a1bf70f0183c80Chris Craik SkMatrix transform; 131259744b79ec302000802cd56d30a1bf70f0183c80Chris Craik renderer.findBestFontTransform(state.mMatrix, &transform); 1313bd3055f95e67a55648fd84a125e939293115171bRomain Guy if (mPrecacheTransform != transform) { 131409c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger fontRenderer.precache(mPaint, mText, mCount, transform); 1315bd3055f95e67a55648fd84a125e939293115171bRomain Guy mPrecacheTransform = transform; 1316bd3055f95e67a55648fd84a125e939293115171bRomain Guy } 131798d608dba6a0b3c15fb08f1fa2c8b9d170124c7cChris Craik deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ? 1318527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik DeferredDisplayList::kOpBatch_Text : 1319527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik DeferredDisplayList::kOpBatch_ColorText; 1320527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 132173fc558e44be259c0833c8c8074ad2333bcb378dKévin PETIT deferInfo.mergeId = reinterpret_cast<mergeid_t>(mPaint->getColor()); 1322527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 1323527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik // don't merge decorated text - the decorations won't draw in order 132498d608dba6a0b3c15fb08f1fa2c8b9d170124c7cChris Craik bool hasDecorations = mPaint->getFlags() 132598d608dba6a0b3c15fb08f1fa2c8b9d170124c7cChris Craik & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag); 132698d608dba6a0b3c15fb08f1fa2c8b9d170124c7cChris Craik 132798d608dba6a0b3c15fb08f1fa2c8b9d170124c7cChris Craik deferInfo.mergeable = state.mMatrix.isPureTranslate() 132898d608dba6a0b3c15fb08f1fa2c8b9d170124c7cChris Craik && !hasDecorations 1329bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik && PaintUtils::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode; 13300f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy } 13310f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy 1332d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 13339b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy Rect bounds; 13343b20251a355c88193c439f928a84ae69483fb488John Reck getLocalBounds(bounds); 1335107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawText(mText, mBytesCount, mCount, mX, mY, 133609c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger mPositions, mPaint, mTotalAdvance, bounds); 13372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 13382af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 133964bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty, 1340272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck const std::vector<OpStatePair>& ops, const Rect& bounds) override { 1341527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik for (unsigned int i = 0; i < ops.size(); i++) { 1342c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik const DeferredDisplayState& state = *(ops[i].state); 134303ae272459869b854e5db252fc81a64a516e111fChris Craik DrawOpMode drawOpMode = (i == ops.size() - 1) ? DrawOpMode::kFlush : DrawOpMode::kDefer; 1344c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik renderer.restoreDisplayState(state, true); // restore all but the clip 1345527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 1346c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik DrawTextOp& op = *((DrawTextOp*)ops[i].op); 13479b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy // quickReject() will not occure in drawText() so we can use mLocalBounds 13489b5a1a28c327e6113d68302b1f0eed1d1c6f6183Romain Guy // directly, we do not need to account for shadow by calling getLocalBounds() 1349107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY, 135009c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger op.mPositions, op.mPaint, op.mTotalAdvance, op.mLocalBounds, 135141541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik drawOpMode); 1352527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 1353527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 1354527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 1355d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 13562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount); 13572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 13582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1359d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawText"; } 13602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 13612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 13622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik const char* mText; 13632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mBytesCount; 13642af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik int mCount; 13652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mX; 13662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik float mY; 13672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik const float* mPositions; 136841541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik float mTotalAdvance; 136959744b79ec302000802cd56d30a1bf70f0183c80Chris Craik SkMatrix mPrecacheTransform; 13702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 13712af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 13722af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik/////////////////////////////////////////////////////////////////////////////// 13732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik// SPECIAL DRAW OPERATIONS 13742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik/////////////////////////////////////////////////////////////////////////////// 13752af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 13762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawFunctorOp : public DrawOp { 13772af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 13782af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik DrawFunctorOp(Functor* functor) 1379d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : DrawOp(nullptr), mFunctor(functor) {} 13802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1381d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 13822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.startMark("GL functor"); 1383107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.callDrawGLFunction(mFunctor, dirty); 13842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik renderer.endMark(); 13852af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 13862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1387d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 13882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik OP_LOG("Draw Functor %p", mFunctor); 13892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 13902af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1391d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawFunctor"; } 13922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 13932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 13942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik Functor* mFunctor; 13952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 13962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1397a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craikclass DrawRenderNodeOp : public DrawBoundedOp { 1398a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik friend class RenderNode; // grant RenderNode access to info of child 13998afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik friend class DisplayListData; // grant DisplayListData access to info of child 14002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 1401a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent, bool clipIsSimple) 1402ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr) 1403ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik , mRenderNode(renderNode) 1404a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik , mRecordedWithPotentialStencilClip(!clipIsSimple || !transformFromParent.isSimple()) 1405ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik , mTransformFromParent(transformFromParent) 1406ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik , mSkipInOrderDraw(false) {} 1407c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 140864bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, 1409d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 14108afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (mRenderNode->isRenderable() && !mSkipInOrderDraw) { 1411a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik mRenderNode->defer(deferStruct, level + 1); 1412ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 1413ff78583d8a73ca35ce65b5d2592570ff6fb9901bChris Craik } 14148afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 141564bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, 1416d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool useQuickReject) override { 14178afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (mRenderNode->isRenderable() && !mSkipInOrderDraw) { 1418a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik mRenderNode->replay(replayStruct, level + 1); 1419c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 1420c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik } 1421c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik 1422d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 142380d4902196899d1325cd9f52c06ae0174cf9bd4cChris Craik LOG_ALWAYS_FATAL("should not be called, because replay() is overridden"); 1424a08f95cfeca7217f9c533b03663bf0dceedd259aChris Craik } 14252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1426d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 1427031e69ff81b696c36284a29e1ea995c5329e291eChris Craik OP_LOG("Draw RenderNode %p %s", mRenderNode, mRenderNode->getName()); 1428a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik if (mRenderNode && (logFlags & kOpLogFlag_Recurse)) { 1429a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik mRenderNode->output(level + 1); 14302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 14312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 14322af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1433d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawRenderNode"; } 14342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1435a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik RenderNode* renderNode() { return mRenderNode; } 1436087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck 14372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 1438a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik RenderNode* mRenderNode; 1439f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik 1440a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik /** 1441a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * This RenderNode was drawn into a DisplayList with the canvas in a state that will likely 1442a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * require rendering with stencil clipping. Either: 1443a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * 1444a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * 1) A path clip or rotated rect clip was in effect on the canvas at record time 1445a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * 2) The RenderNode was recorded with a non-simple canvas transform (e.g. rotation) 1446a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * 1447a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * Note: even if this is false, non-rect clipping may still be applied applied either due to 1448a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * property-driven rotation (either in this RenderNode, or any ancestor), or record time 1449a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * clipping in an ancestor. These are handled in RenderNode::prepareTreeImpl since they are 1450a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * dynamic (relative to a static DisplayList of a parent), and don't affect this flag. 1451a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik */ 1452a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik bool mRecordedWithPotentialStencilClip; 1453a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik 1454f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik /////////////////////////// 1455a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik // Properties below are used by RenderNode::computeOrderingImpl() and issueOperations() 1456f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik /////////////////////////// 1457f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik /** 1458f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik * Records transform vs parent, used for computing total transform without rerunning DL contents 1459f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik */ 1460f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik const mat4 mTransformFromParent; 1461f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik 1462f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik /** 1463a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik * Holds the transformation between the projection surface ViewGroup and this RenderNode 1464b79a3e301a8d89b9e1b1f6f3d7fd6aa56610a6f0Chris Craik * drawing instance. Represents any translations / transformations done within the drawing of 1465b79a3e301a8d89b9e1b1f6f3d7fd6aa56610a6f0Chris Craik * the compositing ancestor ViewGroup's draw, before the draw of the View represented by this 1466b79a3e301a8d89b9e1b1f6f3d7fd6aa56610a6f0Chris Craik * DisplayList draw instance. 1467f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik * 1468a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik * Note: doesn't include transformation within the RenderNode, or its properties. 1469f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik */ 1470f533e947035795a485344f4c270e16507f974901Chris Craik mat4 mTransformFromCompositingAncestor; 1471f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik bool mSkipInOrderDraw; 1472f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik}; 1473f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik 1474f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik/** 1475024433f89684e1f9cb7b15ade7c480c9346fbe4dChris Craik * Not a canvas operation, used only by 3d / z ordering logic in RenderNode::iterate() 1476f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik */ 1477f57776b2d195f0937906eb88b777bb55ccc36967Chris Craikclass DrawShadowOp : public DrawOp { 1478f57776b2d195f0937906eb88b777bb55ccc36967Chris Craikpublic: 1479024433f89684e1f9cb7b15ade7c480c9346fbe4dChris Craik DrawShadowOp(const mat4& transformXY, const mat4& transformZ, 14807466986d2055eb8711f36a85ac539b1572ffe805Chris Craik float casterAlpha, const SkPath* casterOutline) 1481d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : DrawOp(nullptr) 14827466986d2055eb8711f36a85ac539b1572ffe805Chris Craik , mTransformXY(transformXY) 14837466986d2055eb8711f36a85ac539b1572ffe805Chris Craik , mTransformZ(transformZ) 14847466986d2055eb8711f36a85ac539b1572ffe805Chris Craik , mCasterAlpha(casterAlpha) 14857466986d2055eb8711f36a85ac539b1572ffe805Chris Craik , mCasterOutline(casterOutline) { 148661317325b7b4b4ffafd9400ab5966e8d7c67df2eChris Craik } 1487a2fe7affd3d077ac163da90996cb2e5e0ca3b8d1Chris Craik 148864bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, 1489d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const DeferredDisplayState& state) override { 149005f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik renderer.getCaches().tessellationCache.precacheShadows(&state.mMatrix, 14917466986d2055eb8711f36a85ac539b1572ffe805Chris Craik renderer.getLocalClipBounds(), isCasterOpaque(), mCasterOutline, 149205f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius()); 149305f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik } 149405f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik 1495d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 149605f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik TessellationCache::vertexBuffer_pair_t buffers; 1497c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik Matrix4 drawTransform(*(renderer.currentTransform())); 149805f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik renderer.getCaches().tessellationCache.getShadowBuffers(&drawTransform, 14997466986d2055eb8711f36a85ac539b1572ffe805Chris Craik renderer.getLocalClipBounds(), isCasterOpaque(), mCasterOutline, 150005f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius(), 150105f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik buffers); 150205f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik 1503107843de4507b3511006cb9c77b8d0364374385aTom Hudson renderer.drawShadow(mCasterAlpha, buffers.first, buffers.second); 1504f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik } 1505f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik 1506d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 150761317325b7b4b4ffafd9400ab5966e8d7c67df2eChris Craik OP_LOGS("DrawShadow"); 1508f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik } 1509f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik 1510d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawShadow"; } 1511f57776b2d195f0937906eb88b777bb55ccc36967Chris Craik 1512f57776b2d195f0937906eb88b777bb55ccc36967Chris Craikprivate: 1513af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik bool isCasterOpaque() { return mCasterAlpha >= 1.0f; } 151405f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik 1515b79a3e301a8d89b9e1b1f6f3d7fd6aa56610a6f0Chris Craik const mat4 mTransformXY; 1516b79a3e301a8d89b9e1b1f6f3d7fd6aa56610a6f0Chris Craik const mat4 mTransformZ; 1517024433f89684e1f9cb7b15ade7c480c9346fbe4dChris Craik const float mCasterAlpha; 15187466986d2055eb8711f36a85ac539b1572ffe805Chris Craik const SkPath* mCasterOutline; 15192af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 15202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 15212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawLayerOp : public DrawOp { 15222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikpublic: 15233aadd60521960be063ee06208562ccb63dc414e3Chris Craik DrawLayerOp(Layer* layer) 15243aadd60521960be063ee06208562ccb63dc414e3Chris Craik : DrawOp(nullptr), mLayer(layer) {} 15252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1526d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { 15273aadd60521960be063ee06208562ccb63dc414e3Chris Craik renderer.drawLayer(mLayer); 15282af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 15292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1530d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void output(int level, uint32_t logFlags) const override { 15313aadd60521960be063ee06208562ccb63dc414e3Chris Craik OP_LOG("Draw Layer %p", mLayer); 15322af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 15332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 1534d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual const char* name() override { return "DrawLayer"; } 15352af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 15362af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikprivate: 15372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik Layer* mLayer; 15382af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; 15392af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 15402af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; // namespace uirenderer 15412af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}; // namespace android 15422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 15432af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#endif // ANDROID_HWUI_DISPLAY_OPERATION_H 1544