DisplayListCanvas.cpp revision db663fe83f976107fd8fd9307d871b37d9e47370
14aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy/* 24aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Copyright (C) 2010 The Android Open Source Project 34aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 44aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 54aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * you may not use this file except in compliance with the License. 64aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * You may obtain a copy of the License at 74aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 84aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 94aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Unless required by applicable law or agreed to in writing, software 114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * See the License for the specific language governing permissions and 144aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * limitations under the License. 154aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 164aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 17db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik#include "DisplayListCanvas.h" 186554943a1dd6854c0f4976900956e556767b49e1Romain Guy 19a35778c799e8073a42b9e22191bde9d838327ab7John Reck#include "ResourceCache.h" 20c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include "DeferredDisplayList.h" 2112f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck#include "DeferredLayerUpdater.h" 222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#include "DisplayListOp.h" 23113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "RenderNode.h" 248dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson#include "utils/PaintUtils.h" 2513631f3da855f200a151e7837ed9f6b079622b58Romain Guy 26db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik#include <SkCamera.h> 27db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik#include <SkCanvas.h> 28db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik 29db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik#include <private/hwui/DrawGlInfo.h> 30db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik 314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guynamespace android { 324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guynamespace uirenderer { 334aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 34db663fe83f976107fd8fd9307d871b37d9e47370Chris CraikDisplayListCanvas::DisplayListCanvas() 35984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson : mState(*this) 36088c514cb13f3b8f8683588c2f398f18df1547c9John Reck , mResourceCache(ResourceCache::getInstance()) 37d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mDisplayListData(nullptr) 38cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik , mTranslateX(0.0f) 39cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik , mTranslateY(0.0f) 40a5f2e070741182ad9a6ebd489f844f444879c697Rob Tsuk , mHasDeferredTranslate(false) 418afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik , mDeferredBarrierType(kBarrier_None) 42cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik , mHighContrastText(false) 43cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik , mRestoreSaveCount(-1) { 444aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 454aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 46db663fe83f976107fd8fd9307d871b37d9e47370Chris CraikDisplayListCanvas::~DisplayListCanvas() { 4744fd8d24f761f82d21e9b00932648a1b6bf91449John Reck LOG_ALWAYS_FATAL_IF(mDisplayListData, 48db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik "Destroyed a DisplayListCanvas during a record!"); 494aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 504aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 5144fd8d24f761f82d21e9b00932648a1b6bf91449John Reck/////////////////////////////////////////////////////////////////////////////// 5244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck// Operations 5344fd8d24f761f82d21e9b00932648a1b6bf91449John Reck/////////////////////////////////////////////////////////////////////////////// 54d34dd71800d9a1077e58c3b7f2511c46848da417Chet Haase 55db663fe83f976107fd8fd9307d871b37d9e47370Chris CraikDisplayListData* DisplayListCanvas::finishRecording() { 5643ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy mPaintMap.clear(); 57735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy mRegionMap.clear(); 582fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy mPathMap.clear(); 5944fd8d24f761f82d21e9b00932648a1b6bf91449John Reck DisplayListData* data = mDisplayListData; 60d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mDisplayListData = nullptr; 611db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mSkiaCanvasProxy.reset(nullptr); 6244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck return data; 635977baa1fa24125c148a72699b53e62abaf08960Chet Haase} 645977baa1fa24125c148a72699b53e62abaf08960Chet Haase 65db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::prepareDirty(float left, float top, 668dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float right, float bottom) { 6744fd8d24f761f82d21e9b00932648a1b6bf91449John Reck 6844fd8d24f761f82d21e9b00932648a1b6bf91449John Reck LOG_ALWAYS_FATAL_IF(mDisplayListData, 6944fd8d24f761f82d21e9b00932648a1b6bf91449John Reck "prepareDirty called a second time during a recording!"); 7044fd8d24f761f82d21e9b00932648a1b6bf91449John Reck mDisplayListData = new DisplayListData(); 7144fd8d24f761f82d21e9b00932648a1b6bf91449John Reck 72984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3()); 7345e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy 748afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDeferredBarrierType = kBarrier_InOrder; 758dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson mState.setDirtyClip(false); 7627454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy mRestoreSaveCount = -1; 7727454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy} 7827454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy 79db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::finish() { 808afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushRestoreToCount(); 818afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 82107843de4507b3511006cb9c77b8d0364374385aTom Hudson return false; 83b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy} 84b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy 85db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::interrupt() { 86daf98e941e140e8739458126640183b9f296a2abChet Haase} 87daf98e941e140e8739458126640183b9f296a2abChet Haase 88db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::resume() { 894aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 904aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 91db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::callDrawGLFunction(Functor *functor, Rect& dirty) { 92cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy // Ignore dirty during recording, it matters only when we replay 932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addDrawOp(new (alloc()) DrawFunctorOp(functor)); 9409d5cddf67b676018700bcc10a72242641cd7eecJohn Reck mDisplayListData->functors.add(functor); 95daf98e941e140e8739458126640183b9f296a2abChet Haase} 96daf98e941e140e8739458126640183b9f296a2abChet Haase 97db663fe83f976107fd8fd9307d871b37d9e47370Chris CraikSkCanvas* DisplayListCanvas::asSkCanvas() { 981db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger LOG_ALWAYS_FATAL_IF(!mDisplayListData, 991db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger "attempting to get an SkCanvas when we are not recording!"); 1001db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (!mSkiaCanvasProxy) { 1011db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this)); 1021db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 1031db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger return mSkiaCanvasProxy.get(); 1041db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1051db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 106db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikint DisplayListCanvas::save(SkCanvas::SaveFlags flags) { 1078dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addStateOp(new (alloc()) SaveOp((int) flags)); 1088dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return mState.save((int) flags); 1094aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 111db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::restore() { 11204c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy if (mRestoreSaveCount < 0) { 11333f6beb10f98e8ba96250e284876d607055d278dRomain Guy restoreToCount(getSaveCount() - 1); 11433f6beb10f98e8ba96250e284876d607055d278dRomain Guy return; 11504c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy } 11633f6beb10f98e8ba96250e284876d607055d278dRomain Guy 11733f6beb10f98e8ba96250e284876d607055d278dRomain Guy mRestoreSaveCount--; 1188afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 119984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.restore(); 1204aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1214aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 122db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::restoreToCount(int saveCount) { 12327454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy mRestoreSaveCount = saveCount; 1248afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 125984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.restoreToCount(saveCount); 1264aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1274aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 128db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikint DisplayListCanvas::saveLayer(float left, float top, float right, float bottom, 1298dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint* paint, SkCanvas::SaveFlags flags) { 1304ace7305608442ab35ea9aa65a4220df152c187fChris Craik // force matrix/clip isolation for layer 1314ace7305608442ab35ea9aa65a4220df152c187fChris Craik flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag; 1324ace7305608442ab35ea9aa65a4220df152c187fChris Craik 133d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger paint = refPaint(paint); 1348dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags)); 1358dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return mState.save((int) flags); 1365b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy} 1375b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 138db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::translate(float dx, float dy) { 1398afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mHasDeferredTranslate = true; 14033f6beb10f98e8ba96250e284876d607055d278dRomain Guy mTranslateX += dx; 14133f6beb10f98e8ba96250e284876d607055d278dRomain Guy mTranslateY += dy; 1428afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushRestoreToCount(); 1438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson mState.translate(dx, dy, 0.0f); 1444aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1454aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 146db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::rotate(float degrees) { 1472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) RotateOp(degrees)); 148984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.rotate(degrees); 1494aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1504aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 151db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::scale(float sx, float sy) { 1522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ScaleOp(sx, sy)); 153984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.scale(sx, sy); 1544aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1554aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 156db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::skew(float sx, float sy) { 1572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) SkewOp(sx, sy)); 158984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.skew(sx, sy); 159807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy} 160807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy 161db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::setMatrix(const SkMatrix& matrix) { 1622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) SetMatrixOp(matrix)); 163984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.setMatrix(matrix); 1644aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1654aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 166db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::concat(const SkMatrix& matrix) { 1672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ConcatMatrixOp(matrix)); 168984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.concatMatrix(matrix); 1694aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1704aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 171db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::getClipBounds(SkRect* outRect) const { 1728dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson Rect bounds = mState.getLocalClipBounds(); 1738dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom); 1748dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return !(outRect->isEmpty()); 1758dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 1768dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 177db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::quickRejectRect(float left, float top, float right, float bottom) const { 1788dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return mState.quickRejectConservative(left, top, right, bottom); 1798dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 1808dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 181db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::quickRejectPath(const SkPath& path) const { 1828dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkRect bounds = path.getBounds(); 1838dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); 1848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 1858dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 1868dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 187db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipRect(float left, float top, float right, float bottom, 1884aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy SkRegion::Op op) { 1892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); 190984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson return mState.clipRect(left, top, right, bottom, op); 1914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1924aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 193db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipPath(const SkPath* path, SkRegion::Op op) { 1942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik path = refPath(path); 1952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ClipPathOp(path, op)); 196984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson return mState.clipPath(path, op); 197735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy} 198735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy 199db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) { 2002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik region = refRegion(region); 2012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ClipRegionOp(region, op)); 202984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson return mState.clipRegion(region, op); 203735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy} 204735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy 205db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) { 2068afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode"); 2078afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 208cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy // dirty is an out parameter and should not be recorded, 209cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy // it matters only when replaying the display list 210984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *mState.currentTransform()); 2118afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik addRenderNodeOp(op); 2120fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy} 2130fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy 214db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) { 21512f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck // We ref the DeferredLayerUpdater due to its thread-safe ref-counting 21612f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck // semantics. 21712f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck mDisplayListData->ref(layerHandle); 21812f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer(), x, y)); 2196c319ca1275c8db892c39b48fc54864c949f9171Romain Guy} 2206c319ca1275c8db892c39b48fc54864c949f9171Romain Guy 221db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { 2221ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck bitmap = refBitmap(bitmap); 2232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik paint = refPaint(paint); 2242af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 225796475006f5d670e8383a2050f11719522437a43Chris Craik addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint)); 2264aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 2274aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 228db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top, 2298dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint* paint) { 2308dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson save(SkCanvas::kMatrix_SaveFlag); 2318dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson translate(left, top); 2328dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(&bitmap, paint); 2338dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson restore(); 2348dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 2358dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 236db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, 2378dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint* paint) { 2388dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (matrix.isIdentity()) { 2398dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(&bitmap, paint); 2408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))) { 2418dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson // SkMatrix::isScaleTranslate() not available in L 2428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkRect src; 2438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkRect dst; 2448dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bitmap.getBounds(&src); 2458dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson matrix.mapRect(&dst, src); 2468dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, 2478dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint); 2488dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } else { 2498dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson save(SkCanvas::kMatrix_SaveFlag); 2508dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson concat(matrix); 2518dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(&bitmap, paint); 2528dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson restore(); 2538dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } 2548dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 2558dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 256db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop, 2574aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy float srcRight, float srcBottom, float dstLeft, float dstTop, 258d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float dstRight, float dstBottom, const SkPaint* paint) { 259796475006f5d670e8383a2050f11719522437a43Chris Craik if (srcLeft == 0 && srcTop == 0 26014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik && srcRight == bitmap.width() 26114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik && srcBottom == bitmap.height() 262796475006f5d670e8383a2050f11719522437a43Chris Craik && (srcBottom - srcTop == dstBottom - dstTop) 263796475006f5d670e8383a2050f11719522437a43Chris Craik && (srcRight - srcLeft == dstRight - dstLeft)) { 264527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik // transform simple rect to rect drawing case into position bitmap ops, since they merge 265796475006f5d670e8383a2050f11719522437a43Chris Craik save(SkCanvas::kMatrix_SaveFlag); 266796475006f5d670e8383a2050f11719522437a43Chris Craik translate(dstLeft, dstTop); 2678dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(&bitmap, paint); 268796475006f5d670e8383a2050f11719522437a43Chris Craik restore(); 269796475006f5d670e8383a2050f11719522437a43Chris Craik } else { 270796475006f5d670e8383a2050f11719522437a43Chris Craik paint = refPaint(paint); 271796475006f5d670e8383a2050f11719522437a43Chris Craik 27214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik if (paint && paint->getShader()) { 27314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft); 27414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop); 27514100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik if (!MathUtils::areEqual(scaleX, 1.0f) || !MathUtils::areEqual(scaleY, 1.0f)) { 27614100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik // Apply the scale transform on the canvas, so that the shader 27714100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik // effectively calculates positions relative to src rect space 27814100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik 27914100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik save(SkCanvas::kMatrix_SaveFlag); 28014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik translate(dstLeft, dstTop); 28114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik scale(scaleX, scaleY); 28214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik 28314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstLeft = 0.0f; 28414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstTop = 0.0f; 28514100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstRight = srcRight - srcLeft; 28614100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstBottom = srcBottom - srcTop; 28714100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik 2881ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap), 28914100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik srcLeft, srcTop, srcRight, srcBottom, 29014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstLeft, dstTop, dstRight, dstBottom, paint)); 29114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik restore(); 29214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik return; 29314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik } 29414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik } 29514100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik 2961ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap), 297796475006f5d670e8383a2050f11719522437a43Chris Craik srcLeft, srcTop, srcRight, srcBottom, 298796475006f5d670e8383a2050f11719522437a43Chris Craik dstLeft, dstTop, dstRight, dstBottom, paint)); 299527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 3004aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3014aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 302db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight, 303d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const float* vertices, const int* colors, const SkPaint* paint) { 3040664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik int vertexCount = (meshWidth + 1) * (meshHeight + 1); 3050664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex 3062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik paint = refPaint(paint); 3070664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex 3082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3091ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck addDrawOp(new (alloc()) DrawBitmapMeshOp(refBitmap(&bitmap), meshWidth, meshHeight, 3108dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson vertices, colors, paint)); 3115a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy} 3125a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy 313db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, 314d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float left, float top, float right, float bottom, const SkPaint* paint) { 3151ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck bitmap = refBitmap(bitmap); 316e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy patch = refPatch(patch); 31716ea8d373b03b1e115dd505af70dbee4e3a3a182Romain Guy paint = refPaint(paint); 3182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3191ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint)); 3204aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3214aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 322db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawColor(int color, SkXfermode::Mode mode) { 3232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addDrawOp(new (alloc()) DrawColorOp(color, mode)); 3244aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3254aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 326db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPaint(const SkPaint& paint) { 3278dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkRect bounds; 3288dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (getClipBounds(&bounds)) { 3298dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint); 3308dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } 3318dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 3328dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 3338dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 334db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRect(float left, float top, float right, float bottom, 3358dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint& paint) { 3368dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, refPaint(&paint))); 3374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3384aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 339db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRoundRect(float left, float top, float right, float bottom, 3408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float rx, float ry, const SkPaint& paint) { 3418dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, refPaint(&paint))); 34201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 34301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 344db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRoundRect( 345072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, 346072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, 347072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, 348072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi CanvasPropertyPaint* paint) { 3490e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(left); 3500e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(top); 3510e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(right); 3520e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(bottom); 3530e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(rx); 3540e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(ry); 3550e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(paint); 356072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value, 357072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi &right->value, &bottom->value, &rx->value, &ry->value, &paint->value)); 358072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi} 359072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi 360db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { 3618dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, refPaint(&paint))); 36201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 36301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 364db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, 36552244fff29042926e21fa897ef5ab11148e35299John Reck CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { 3660e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(x); 3670e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(y); 3680e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(radius); 3690e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(paint); 37052244fff29042926e21fa897ef5ab11148e35299John Reck addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value, 37152244fff29042926e21fa897ef5ab11148e35299John Reck &radius->value, &paint->value)); 37252244fff29042926e21fa897ef5ab11148e35299John Reck} 37352244fff29042926e21fa897ef5ab11148e35299John Reck 374db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawOval(float left, float top, float right, float bottom, 3758dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint& paint) { 3768dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, refPaint(&paint))); 377c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy} 378c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 379db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawArc(float left, float top, float right, float bottom, 3808dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) { 381544e524db6e4da526af1c897fe5314036ede5012Chris Craik if (fabs(sweepAngle) >= 360.0f) { 382107843de4507b3511006cb9c77b8d0364374385aTom Hudson drawOval(left, top, right, bottom, paint); 383107843de4507b3511006cb9c77b8d0364374385aTom Hudson } else { 384107843de4507b3511006cb9c77b8d0364374385aTom Hudson addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, 3858dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson startAngle, sweepAngle, useCenter, refPaint(&paint))); 3866ac174b97246ed40fe780b29561603b61770fa17Chris Craik } 3878b2f5267f16c295f12faab810527cd6311997e34Romain Guy} 3888b2f5267f16c295f12faab810527cd6311997e34Romain Guy 389db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 3908dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawPathOp(refPath(&path), refPaint(&paint))); 3914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3924aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 393db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawLines(const float* points, int count, const SkPaint& paint) { 3942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik points = refBuffer<float>(points, count); 3952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3968dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawLinesOp(points, count, refPaint(&paint))); 397ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy} 398ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy 399db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPoints(const float* points, int count, const SkPaint& paint) { 4002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik points = refBuffer<float>(points, count); 4012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4028dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawPointsOp(points, count, refPaint(&paint))); 4034aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 4044aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 405db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawTextOnPath(const uint16_t* glyphs, int count, 4068dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) { 4078dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (!glyphs || count <= 0) return; 4082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4098dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int bytesCount = 2 * count; 4108dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson DrawOp* op = new (alloc()) DrawTextOnPathOp(refText((const char*) glyphs, bytesCount), 4118dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bytesCount, count, refPath(&path), 4128dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson hOffset, vOffset, refPaint(&paint)); 4130f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy addDrawOp(op); 414996e57c84368058be793897ebc355b917a59abc2Raph Levien} 415996e57c84368058be793897ebc355b917a59abc2Raph Levien 416db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPosText(const uint16_t* text, const float* positions, 4178dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int count, int posCount, const SkPaint& paint) { 418107843de4507b3511006cb9c77b8d0364374385aTom Hudson if (!text || count <= 0) return; 4192af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4208dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int bytesCount = 2 * count; 4212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik positions = refBuffer<float>(positions, count * 2); 4222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4238dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson DrawOp* op = new (alloc()) DrawPosTextOp(refText((const char*) text, bytesCount), 4248dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bytesCount, count, positions, refPaint(&paint)); 4250f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy addDrawOp(op); 426996e57c84368058be793897ebc355b917a59abc2Raph Levien} 427996e57c84368058be793897ebc355b917a59abc2Raph Levien 428cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craikstatic void simplifyPaint(int color, SkPaint* paint) { 429cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik paint->setColor(color); 430d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik paint->setShader(nullptr); 431d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik paint->setColorFilter(nullptr); 432d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik paint->setLooper(nullptr); 433cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik paint->setStrokeWidth(4 + 0.04 * paint->getTextSize()); 434cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik paint->setStrokeJoin(SkPaint::kRound_Join); 435d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik paint->setLooper(nullptr); 436cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik} 437cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik 438db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions, 4398dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int count, const SkPaint& paint, float x, float y, 4408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, 4418dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float totalAdvance) { 442527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 4438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; 44433f6beb10f98e8ba96250e284876d607055d278dRomain Guy 4458dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int bytesCount = count * 2; 4468dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const char* text = refText((const char*) glyphs, bytesCount); 4472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik positions = refBuffer<float>(positions, count * 2); 4488dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom); 44933f6beb10f98e8ba96250e284876d607055d278dRomain Guy 450cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik if (CC_UNLIKELY(mHighContrastText)) { 451cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik // high contrast draw path 4528dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int color = paint.getColor(); 453cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color); 454cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik bool darken = channelSum < (128 * 3); 455cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik 456cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik // outline 4578dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkPaint* outlinePaint = copyPaint(&paint); 458cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, outlinePaint); 459cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik outlinePaint->setStyle(SkPaint::kStrokeAndFill_Style); 460cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, 461cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik x, y, positions, outlinePaint, totalAdvance, bounds)); // bounds? 462cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik 463cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik // inner 4648dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkPaint* innerPaint = copyPaint(&paint); 465cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, innerPaint); 466cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik innerPaint->setStyle(SkPaint::kFill_Style); 467cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, 468cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik x, y, positions, innerPaint, totalAdvance, bounds)); 469cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik } else { 470cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik // standard draw path 471cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, 4728dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson x, y, positions, refPaint(&paint), totalAdvance, bounds); 473cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik addDrawOp(op); 474cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik } 475672433d90fab7383cd28beac9d4485b566a90940Romain Guy} 476672433d90fab7383cd28beac9d4485b566a90940Romain Guy 477db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRects(const float* rects, int count, const SkPaint* paint) { 478107843de4507b3511006cb9c77b8d0364374385aTom Hudson if (count <= 0) return; 479672433d90fab7383cd28beac9d4485b566a90940Romain Guy 4802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik rects = refBuffer<float>(rects, count); 4812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik paint = refPaint(paint); 4822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint)); 483eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy} 484eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy 485db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::setDrawFilter(SkDrawFilter* filter) { 4860b8606266c1afc69cbeb73acda67c85d87943318Derek Sollenberger mDrawFilter.reset(SkSafeRef(filter)); 4872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik} 4882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 489db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::insertReorderBarrier(bool enableReorder) { 4908afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushRestoreToCount(); 4918afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 4928afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDeferredBarrierType = enableReorder ? kBarrier_OutOfOrder : kBarrier_InOrder; 4938afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik} 4948afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 495db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::flushRestoreToCount() { 4962af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik if (mRestoreSaveCount >= 0) { 4978afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik addOpAndUpdateChunk(new (alloc()) RestoreToCountOp(mRestoreSaveCount)); 4982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mRestoreSaveCount = -1; 4992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik} 5012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 502db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::flushTranslate() { 5038afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (mHasDeferredTranslate) { 5042af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik if (mTranslateX != 0.0f || mTranslateY != 0.0f) { 5058afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik addOpAndUpdateChunk(new (alloc()) TranslateOp(mTranslateX, mTranslateY)); 5062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mTranslateX = mTranslateY = 0.0f; 5072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5088afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mHasDeferredTranslate = false; 5092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik} 5112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 512db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) { 5138afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik int insertIndex = mDisplayListData->displayListOps.add(op); 5148afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (mDeferredBarrierType != kBarrier_None) { 5158afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // op is first in new chunk 5168afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDisplayListData->chunks.push(); 5178afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik DisplayListData::Chunk& newChunk = mDisplayListData->chunks.editTop(); 5188afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik newChunk.beginOpIndex = insertIndex; 5198afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik newChunk.endOpIndex = insertIndex + 1; 5208afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder); 5218afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 5228afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik int nextChildIndex = mDisplayListData->children().size(); 5238afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex; 5248afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDeferredBarrierType = kBarrier_None; 5258afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik } else { 5268afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // standard case - append to existing chunk 5278afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDisplayListData->chunks.editTop().endOpIndex = insertIndex + 1; 5288afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik } 5298afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return insertIndex; 5302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik} 5312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 532db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::flushAndAddOp(DisplayListOp* op) { 5338afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushRestoreToCount(); 5348afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 5358afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return addOpAndUpdateChunk(op); 5368afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik} 5378afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 538db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addStateOp(StateOp* op) { 5398afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return flushAndAddOp(op); 5408afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik} 5418afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 542db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addDrawOp(DrawOp* op) { 5432af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik Rect localBounds; 5443b20251a355c88193c439f928a84ae69483fb488John Reck if (op->getLocalBounds(localBounds)) { 5458dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bool rejected = quickRejectRect(localBounds.left, localBounds.top, 5462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik localBounds.right, localBounds.bottom); 5472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik op->setQuickRejected(rejected); 5482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 549c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik 55044fd8d24f761f82d21e9b00932648a1b6bf91449John Reck mDisplayListData->hasDrawOps = true; 5518afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return flushAndAddOp(op); 5528afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik} 5538afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 554db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addRenderNodeOp(DrawRenderNodeOp* op) { 5558afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik int opIndex = addDrawOp(op); 5568afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik int childIndex = mDisplayListData->addChild(op); 5578afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 5588afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // update the chunk's child indices 5598afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik DisplayListData::Chunk& chunk = mDisplayListData->chunks.editTop(); 5608afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik chunk.endChildIndex = childIndex + 1; 5618afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 5628afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (op->renderNode()->stagingProperties().isProjectionReceiver()) { 5638afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // use staging property, since recording on UI thread 5648afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDisplayListData->projectionReceiveIndex = opIndex; 5658afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik } 5668afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return opIndex; 5675ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy} 5685ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy 5694aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace uirenderer 5704aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace android 571