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