DisplayListCanvas.cpp revision 956f340aacc7d8fc2d10f776551f13fde2d8d3ab
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 91956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craikvoid DisplayListCanvas::callDrawGLFunction(Functor *functor) { 922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addDrawOp(new (alloc()) DrawFunctorOp(functor)); 9309d5cddf67b676018700bcc10a72242641cd7eecJohn Reck mDisplayListData->functors.add(functor); 94daf98e941e140e8739458126640183b9f296a2abChet Haase} 95daf98e941e140e8739458126640183b9f296a2abChet Haase 96db663fe83f976107fd8fd9307d871b37d9e47370Chris CraikSkCanvas* DisplayListCanvas::asSkCanvas() { 971db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger LOG_ALWAYS_FATAL_IF(!mDisplayListData, 981db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger "attempting to get an SkCanvas when we are not recording!"); 991db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (!mSkiaCanvasProxy) { 1001db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this)); 1011db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 1021db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger return mSkiaCanvasProxy.get(); 1031db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1041db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 105db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikint DisplayListCanvas::save(SkCanvas::SaveFlags flags) { 1068dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addStateOp(new (alloc()) SaveOp((int) flags)); 1078dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return mState.save((int) flags); 1084aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1094aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 110db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::restore() { 11104c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy if (mRestoreSaveCount < 0) { 11233f6beb10f98e8ba96250e284876d607055d278dRomain Guy restoreToCount(getSaveCount() - 1); 11333f6beb10f98e8ba96250e284876d607055d278dRomain Guy return; 11404c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy } 11533f6beb10f98e8ba96250e284876d607055d278dRomain Guy 11633f6beb10f98e8ba96250e284876d607055d278dRomain Guy mRestoreSaveCount--; 1178afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 118984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.restore(); 1194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1204aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 121db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::restoreToCount(int saveCount) { 12227454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy mRestoreSaveCount = saveCount; 1238afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 124984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.restoreToCount(saveCount); 1254aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1264aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 127db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikint DisplayListCanvas::saveLayer(float left, float top, float right, float bottom, 1288dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint* paint, SkCanvas::SaveFlags flags) { 1294ace7305608442ab35ea9aa65a4220df152c187fChris Craik // force matrix/clip isolation for layer 1304ace7305608442ab35ea9aa65a4220df152c187fChris Craik flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag; 1314ace7305608442ab35ea9aa65a4220df152c187fChris Craik 132d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger paint = refPaint(paint); 1338dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags)); 1348dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return mState.save((int) flags); 1355b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy} 1365b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy 137db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::translate(float dx, float dy) { 1388afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mHasDeferredTranslate = true; 13933f6beb10f98e8ba96250e284876d607055d278dRomain Guy mTranslateX += dx; 14033f6beb10f98e8ba96250e284876d607055d278dRomain Guy mTranslateY += dy; 1418afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushRestoreToCount(); 1428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson mState.translate(dx, dy, 0.0f); 1434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1444aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 145db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::rotate(float degrees) { 1462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) RotateOp(degrees)); 147984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.rotate(degrees); 1484aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1494aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 150db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::scale(float sx, float sy) { 1512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ScaleOp(sx, sy)); 152984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.scale(sx, sy); 1534aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1544aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 155db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::skew(float sx, float sy) { 1562af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) SkewOp(sx, sy)); 157984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.skew(sx, sy); 158807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy} 159807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy 160db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::setMatrix(const SkMatrix& matrix) { 1612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) SetMatrixOp(matrix)); 162984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.setMatrix(matrix); 1634aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1644aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 165db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::concat(const SkMatrix& matrix) { 1662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ConcatMatrixOp(matrix)); 167984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson mState.concatMatrix(matrix); 1684aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1694aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 170db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::getClipBounds(SkRect* outRect) const { 1718dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson Rect bounds = mState.getLocalClipBounds(); 1728dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom); 1738dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return !(outRect->isEmpty()); 1748dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 1758dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 176db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::quickRejectRect(float left, float top, float right, float bottom) const { 1778dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return mState.quickRejectConservative(left, top, right, bottom); 1788dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 1798dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 180db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::quickRejectPath(const SkPath& path) const { 1818dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkRect bounds = path.getBounds(); 1828dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); 1838dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 1848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 1858dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 186db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipRect(float left, float top, float right, float bottom, 1874aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy SkRegion::Op op) { 1882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); 189984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson return mState.clipRect(left, top, right, bottom, op); 1904aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 1914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 192db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipPath(const SkPath* path, SkRegion::Op op) { 1932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik path = refPath(path); 1942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ClipPathOp(path, op)); 195984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson return mState.clipPath(path, op); 196735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy} 197735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy 198db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) { 1992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik region = refRegion(region); 2002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addStateOp(new (alloc()) ClipRegionOp(region, op)); 201984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson return mState.clipRegion(region, op); 202735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy} 203735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy 204956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craikvoid DisplayListCanvas::drawRenderNode(RenderNode* renderNode) { 2058afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode"); 2068afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 207cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy // dirty is an out parameter and should not be recorded, 208cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy // it matters only when replaying the display list 209956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craik DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, *mState.currentTransform()); 2108afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik addRenderNodeOp(op); 2110fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy} 2120fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy 213db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) { 21412f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck // We ref the DeferredLayerUpdater due to its thread-safe ref-counting 21512f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck // semantics. 21612f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck mDisplayListData->ref(layerHandle); 21712f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer(), x, y)); 2186c319ca1275c8db892c39b48fc54864c949f9171Romain Guy} 2196c319ca1275c8db892c39b48fc54864c949f9171Romain Guy 220db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { 2211ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck bitmap = refBitmap(bitmap); 2222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik paint = refPaint(paint); 2232af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 224796475006f5d670e8383a2050f11719522437a43Chris Craik addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint)); 2254aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 2264aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 227db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top, 2288dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint* paint) { 2298dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson save(SkCanvas::kMatrix_SaveFlag); 2308dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson translate(left, top); 2318dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(&bitmap, paint); 2328dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson restore(); 2338dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 2348dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 235db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, 2368dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint* paint) { 2378dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (matrix.isIdentity()) { 2388dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(&bitmap, paint); 2398dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))) { 2408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson // SkMatrix::isScaleTranslate() not available in L 2418dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkRect src; 2428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkRect dst; 2438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bitmap.getBounds(&src); 2448dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson matrix.mapRect(&dst, src); 2458dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, 2468dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint); 2478dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } else { 2488dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson save(SkCanvas::kMatrix_SaveFlag); 2498dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson concat(matrix); 2508dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(&bitmap, paint); 2518dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson restore(); 2528dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } 2538dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 2548dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 255db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop, 2564aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy float srcRight, float srcBottom, float dstLeft, float dstTop, 257d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float dstRight, float dstBottom, const SkPaint* paint) { 258796475006f5d670e8383a2050f11719522437a43Chris Craik if (srcLeft == 0 && srcTop == 0 25914100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik && srcRight == bitmap.width() 26014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik && srcBottom == bitmap.height() 261796475006f5d670e8383a2050f11719522437a43Chris Craik && (srcBottom - srcTop == dstBottom - dstTop) 262796475006f5d670e8383a2050f11719522437a43Chris Craik && (srcRight - srcLeft == dstRight - dstLeft)) { 263527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik // transform simple rect to rect drawing case into position bitmap ops, since they merge 264796475006f5d670e8383a2050f11719522437a43Chris Craik save(SkCanvas::kMatrix_SaveFlag); 265796475006f5d670e8383a2050f11719522437a43Chris Craik translate(dstLeft, dstTop); 2668dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawBitmap(&bitmap, paint); 267796475006f5d670e8383a2050f11719522437a43Chris Craik restore(); 268796475006f5d670e8383a2050f11719522437a43Chris Craik } else { 269796475006f5d670e8383a2050f11719522437a43Chris Craik paint = refPaint(paint); 270796475006f5d670e8383a2050f11719522437a43Chris Craik 27114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik if (paint && paint->getShader()) { 27214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft); 27314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop); 27414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik if (!MathUtils::areEqual(scaleX, 1.0f) || !MathUtils::areEqual(scaleY, 1.0f)) { 27514100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik // Apply the scale transform on the canvas, so that the shader 27614100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik // effectively calculates positions relative to src rect space 27714100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik 27814100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik save(SkCanvas::kMatrix_SaveFlag); 27914100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik translate(dstLeft, dstTop); 28014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik scale(scaleX, scaleY); 28114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik 28214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstLeft = 0.0f; 28314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstTop = 0.0f; 28414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstRight = srcRight - srcLeft; 28514100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstBottom = srcBottom - srcTop; 28614100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik 2871ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap), 28814100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik srcLeft, srcTop, srcRight, srcBottom, 28914100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik dstLeft, dstTop, dstRight, dstBottom, paint)); 29014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik restore(); 29114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik return; 29214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik } 29314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik } 29414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik 2951ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap), 296796475006f5d670e8383a2050f11719522437a43Chris Craik srcLeft, srcTop, srcRight, srcBottom, 297796475006f5d670e8383a2050f11719522437a43Chris Craik dstLeft, dstTop, dstRight, dstBottom, paint)); 298527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik } 2994aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3004aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 301db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight, 302d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik const float* vertices, const int* colors, const SkPaint* paint) { 3030664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik int vertexCount = (meshWidth + 1) * (meshHeight + 1); 3040664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex 3052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik paint = refPaint(paint); 3060664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex 3072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3081ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck addDrawOp(new (alloc()) DrawBitmapMeshOp(refBitmap(&bitmap), meshWidth, meshHeight, 3098dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson vertices, colors, paint)); 3105a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy} 3115a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy 312db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, 313d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik float left, float top, float right, float bottom, const SkPaint* paint) { 3141ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck bitmap = refBitmap(bitmap); 315e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy patch = refPatch(patch); 31616ea8d373b03b1e115dd505af70dbee4e3a3a182Romain Guy paint = refPaint(paint); 3172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3181ff961dd6d51247e82e41de052f04fd0b577f09bJohn Reck addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint)); 3194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3204aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 321db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawColor(int color, SkXfermode::Mode mode) { 3222af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addDrawOp(new (alloc()) DrawColorOp(color, mode)); 3234aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3244aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 325db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPaint(const SkPaint& paint) { 3268dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkRect bounds; 3278dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (getClipBounds(&bounds)) { 3288dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint); 3298dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson } 3308dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson} 3318dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 3328dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson 333db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRect(float left, float top, float right, float bottom, 3348dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint& paint) { 3358dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, refPaint(&paint))); 3364aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 338db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRoundRect(float left, float top, float right, float bottom, 3398dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float rx, float ry, const SkPaint& paint) { 3408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, refPaint(&paint))); 34101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 34201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 343db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRoundRect( 344072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, 345072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, 346072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, 347072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi CanvasPropertyPaint* paint) { 3480e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(left); 3490e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(top); 3500e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(right); 3510e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(bottom); 3520e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(rx); 3530e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(ry); 3540e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(paint); 355072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value, 356072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi &right->value, &bottom->value, &rx->value, &ry->value, &paint->value)); 357072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi} 358072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi 359db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { 3608dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, refPaint(&paint))); 36101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 36201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 363db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, 36452244fff29042926e21fa897ef5ab11148e35299John Reck CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { 3650e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(x); 3660e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(y); 3670e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(radius); 3680e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mDisplayListData->ref(paint); 36952244fff29042926e21fa897ef5ab11148e35299John Reck addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value, 37052244fff29042926e21fa897ef5ab11148e35299John Reck &radius->value, &paint->value)); 37152244fff29042926e21fa897ef5ab11148e35299John Reck} 37252244fff29042926e21fa897ef5ab11148e35299John Reck 373db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawOval(float left, float top, float right, float bottom, 3748dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPaint& paint) { 3758dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, refPaint(&paint))); 376c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy} 377c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 378db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawArc(float left, float top, float right, float bottom, 3798dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) { 380544e524db6e4da526af1c897fe5314036ede5012Chris Craik if (fabs(sweepAngle) >= 360.0f) { 381107843de4507b3511006cb9c77b8d0364374385aTom Hudson drawOval(left, top, right, bottom, paint); 382107843de4507b3511006cb9c77b8d0364374385aTom Hudson } else { 383107843de4507b3511006cb9c77b8d0364374385aTom Hudson addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, 3848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson startAngle, sweepAngle, useCenter, refPaint(&paint))); 3856ac174b97246ed40fe780b29561603b61770fa17Chris Craik } 3868b2f5267f16c295f12faab810527cd6311997e34Romain Guy} 3878b2f5267f16c295f12faab810527cd6311997e34Romain Guy 388db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 3898dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawPathOp(refPath(&path), refPaint(&paint))); 3904aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 3914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 392db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawLines(const float* points, int count, const SkPaint& paint) { 3932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik points = refBuffer<float>(points, count); 3942af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 3958dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawLinesOp(points, count, refPaint(&paint))); 396ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy} 397ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy 398db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPoints(const float* points, int count, const SkPaint& paint) { 3992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik points = refBuffer<float>(points, count); 4002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4018dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson addDrawOp(new (alloc()) DrawPointsOp(points, count, refPaint(&paint))); 4024aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy} 4034aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 404db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawTextOnPath(const uint16_t* glyphs, int count, 4058dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) { 4068dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (!glyphs || count <= 0) return; 4072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4088dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int bytesCount = 2 * count; 4098dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson DrawOp* op = new (alloc()) DrawTextOnPathOp(refText((const char*) glyphs, bytesCount), 4108dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bytesCount, count, refPath(&path), 4118dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson hOffset, vOffset, refPaint(&paint)); 4120f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy addDrawOp(op); 413996e57c84368058be793897ebc355b917a59abc2Raph Levien} 414996e57c84368058be793897ebc355b917a59abc2Raph Levien 415db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPosText(const uint16_t* text, const float* positions, 4168dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int count, int posCount, const SkPaint& paint) { 417107843de4507b3511006cb9c77b8d0364374385aTom Hudson if (!text || count <= 0) return; 4182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4198dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int bytesCount = 2 * count; 4202af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik positions = refBuffer<float>(positions, count * 2); 4212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 4228dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson DrawOp* op = new (alloc()) DrawPosTextOp(refText((const char*) text, bytesCount), 4238dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bytesCount, count, positions, refPaint(&paint)); 4240f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy addDrawOp(op); 425996e57c84368058be793897ebc355b917a59abc2Raph Levien} 426996e57c84368058be793897ebc355b917a59abc2Raph Levien 427cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craikstatic void simplifyPaint(int color, SkPaint* paint) { 428cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik paint->setColor(color); 429d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik paint->setShader(nullptr); 430d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik paint->setColorFilter(nullptr); 431d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik paint->setLooper(nullptr); 432cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik paint->setStrokeWidth(4 + 0.04 * paint->getTextSize()); 433cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik paint->setStrokeJoin(SkPaint::kRound_Join); 434d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik paint->setLooper(nullptr); 435cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik} 436cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik 437db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions, 4388dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int count, const SkPaint& paint, float x, float y, 4398dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float boundsLeft, float boundsTop, float boundsRight, float boundsBottom, 4408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson float totalAdvance) { 441527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik 4428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; 44333f6beb10f98e8ba96250e284876d607055d278dRomain Guy 4448dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int bytesCount = count * 2; 4458dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson const char* text = refText((const char*) glyphs, bytesCount); 4462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik positions = refBuffer<float>(positions, count * 2); 4478dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom); 44833f6beb10f98e8ba96250e284876d607055d278dRomain Guy 449cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik if (CC_UNLIKELY(mHighContrastText)) { 450cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik // high contrast draw path 4518dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson int color = paint.getColor(); 452cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color); 453cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik bool darken = channelSum < (128 * 3); 454cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik 455cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik // outline 4568dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkPaint* outlinePaint = copyPaint(&paint); 457cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, outlinePaint); 458cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik outlinePaint->setStyle(SkPaint::kStrokeAndFill_Style); 459cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, 460cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik x, y, positions, outlinePaint, totalAdvance, bounds)); // bounds? 461cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik 462cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik // inner 4638dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson SkPaint* innerPaint = copyPaint(&paint); 464cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, innerPaint); 465cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik innerPaint->setStyle(SkPaint::kFill_Style); 466cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count, 467cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik x, y, positions, innerPaint, totalAdvance, bounds)); 468cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik } else { 469cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik // standard draw path 470cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, 4718dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson x, y, positions, refPaint(&paint), totalAdvance, bounds); 472cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik addDrawOp(op); 473cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik } 474672433d90fab7383cd28beac9d4485b566a90940Romain Guy} 475672433d90fab7383cd28beac9d4485b566a90940Romain Guy 476db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRects(const float* rects, int count, const SkPaint* paint) { 477107843de4507b3511006cb9c77b8d0364374385aTom Hudson if (count <= 0) return; 478672433d90fab7383cd28beac9d4485b566a90940Romain Guy 4792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik rects = refBuffer<float>(rects, count); 4802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik paint = refPaint(paint); 4812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint)); 482eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy} 483eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy 484db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::setDrawFilter(SkDrawFilter* filter) { 4850b8606266c1afc69cbeb73acda67c85d87943318Derek Sollenberger mDrawFilter.reset(SkSafeRef(filter)); 4862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik} 4872af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 488db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::insertReorderBarrier(bool enableReorder) { 4898afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushRestoreToCount(); 4908afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 4918afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDeferredBarrierType = enableReorder ? kBarrier_OutOfOrder : kBarrier_InOrder; 4928afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik} 4938afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 494db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::flushRestoreToCount() { 4952af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik if (mRestoreSaveCount >= 0) { 4968afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik addOpAndUpdateChunk(new (alloc()) RestoreToCountOp(mRestoreSaveCount)); 4972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mRestoreSaveCount = -1; 4982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 4992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik} 5002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 501db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::flushTranslate() { 5028afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (mHasDeferredTranslate) { 5032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik if (mTranslateX != 0.0f || mTranslateY != 0.0f) { 5048afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik addOpAndUpdateChunk(new (alloc()) TranslateOp(mTranslateX, mTranslateY)); 5052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik mTranslateX = mTranslateY = 0.0f; 5062af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5078afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mHasDeferredTranslate = false; 5082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 5092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik} 5102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 511db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) { 5128afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik int insertIndex = mDisplayListData->displayListOps.add(op); 5138afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (mDeferredBarrierType != kBarrier_None) { 5148afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // op is first in new chunk 5158afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDisplayListData->chunks.push(); 5168afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik DisplayListData::Chunk& newChunk = mDisplayListData->chunks.editTop(); 5178afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik newChunk.beginOpIndex = insertIndex; 5188afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik newChunk.endOpIndex = insertIndex + 1; 5198afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder); 5208afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 5218afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik int nextChildIndex = mDisplayListData->children().size(); 5228afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex; 5238afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDeferredBarrierType = kBarrier_None; 5248afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik } else { 5258afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // standard case - append to existing chunk 5268afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDisplayListData->chunks.editTop().endOpIndex = insertIndex + 1; 5278afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik } 5288afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return insertIndex; 5292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik} 5302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik 531db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::flushAndAddOp(DisplayListOp* op) { 5328afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushRestoreToCount(); 5338afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik flushTranslate(); 5348afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return addOpAndUpdateChunk(op); 5358afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik} 5368afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 537db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addStateOp(StateOp* op) { 5388afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return flushAndAddOp(op); 5398afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik} 5408afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 541db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addDrawOp(DrawOp* op) { 5422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik Rect localBounds; 5433b20251a355c88193c439f928a84ae69483fb488John Reck if (op->getLocalBounds(localBounds)) { 5448dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson bool rejected = quickRejectRect(localBounds.left, localBounds.top, 5452af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik localBounds.right, localBounds.bottom); 5462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik op->setQuickRejected(rejected); 5472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik } 548c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik 54944fd8d24f761f82d21e9b00932648a1b6bf91449John Reck mDisplayListData->hasDrawOps = true; 5508afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return flushAndAddOp(op); 5518afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik} 5528afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 553db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addRenderNodeOp(DrawRenderNodeOp* op) { 5548afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik int opIndex = addDrawOp(op); 5558afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik int childIndex = mDisplayListData->addChild(op); 5568afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 5578afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // update the chunk's child indices 5588afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik DisplayListData::Chunk& chunk = mDisplayListData->chunks.editTop(); 5598afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik chunk.endChildIndex = childIndex + 1; 5608afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik 5618afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (op->renderNode()->stagingProperties().isProjectionReceiver()) { 5628afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // use staging property, since recording on UI thread 5638afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik mDisplayListData->projectionReceiveIndex = opIndex; 5648afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik } 5658afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik return opIndex; 5665ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy} 5675ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy 5684aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace uirenderer 5694aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace android 570