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
19c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include "DeferredDisplayList.h"
2012f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck#include "DeferredLayerUpdater.h"
212af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#include "DisplayListOp.h"
22766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#include "ResourceCache.h"
23113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "RenderNode.h"
24766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#include "VectorDrawable.h"
258dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson#include "utils/PaintUtils.h"
2613631f3da855f200a151e7837ed9f6b079622b58Romain Guy
27db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik#include <SkCamera.h>
28db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik#include <SkCanvas.h>
29db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik
30db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik#include <private/hwui/DrawGlInfo.h>
31db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik
324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guynamespace android {
334aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guynamespace uirenderer {
344aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
35cc882b6518129a11fa007f8c9343e972f03607b4Derek SollenbergerDisplayListCanvas::DisplayListCanvas(int width, int height)
36984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    : mState(*this)
37088c514cb13f3b8f8683588c2f398f18df1547c9John Reck    , mResourceCache(ResourceCache::getInstance())
38003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    , mDisplayList(nullptr)
39cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    , mTranslateX(0.0f)
40cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    , mTranslateY(0.0f)
41a5f2e070741182ad9a6ebd489f844f444879c697Rob Tsuk    , mHasDeferredTranslate(false)
428afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    , mDeferredBarrierType(kBarrier_None)
43cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    , mHighContrastText(false)
44cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    , mRestoreSaveCount(-1) {
456f485569fa3d6047dcffd068aebf361e3598783cDerek Sollenberger    resetRecording(width, height);
464aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
474aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
48db663fe83f976107fd8fd9307d871b37d9e47370Chris CraikDisplayListCanvas::~DisplayListCanvas() {
49003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    LOG_ALWAYS_FATAL_IF(mDisplayList,
50db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik            "Destroyed a DisplayListCanvas during a record!");
514aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
524aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
536f485569fa3d6047dcffd068aebf361e3598783cDerek Sollenbergervoid DisplayListCanvas::resetRecording(int width, int height) {
54003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    LOG_ALWAYS_FATAL_IF(mDisplayList,
5544fd8d24f761f82d21e9b00932648a1b6bf91449John Reck            "prepareDirty called a second time during a recording!");
56003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList = new DisplayList();
5744fd8d24f761f82d21e9b00932648a1b6bf91449John Reck
5864e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik    mState.initializeSaveStack(width, height,
5964e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik            0, 0, width, height, Vector3());
6045e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy
618afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    mDeferredBarrierType = kBarrier_InOrder;
628dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    mState.setDirtyClip(false);
6327454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    mRestoreSaveCount = -1;
6427454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy}
6527454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy
66cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger
67cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
68cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger// Operations
69cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
70cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger
71003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris CraikDisplayList* DisplayListCanvas::finishRecording() {
728afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushRestoreToCount();
738afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
74daf98e941e140e8739458126640183b9f296a2abChet Haase
75cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger    mPaintMap.clear();
76cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger    mRegionMap.clear();
77cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger    mPathMap.clear();
78003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    DisplayList* displayList = mDisplayList;
79003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList = nullptr;
80cc882b6518129a11fa007f8c9343e972f03607b4Derek Sollenberger    mSkiaCanvasProxy.reset(nullptr);
81003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    return displayList;
824aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
834aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
84cd1c3eba69d044b551cededad75474038f919890John Reckvoid DisplayListCanvas::callDrawGLFunction(Functor* functor,
85cd1c3eba69d044b551cededad75474038f919890John Reck        GlFunctorLifecycleListener* listener) {
862af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawFunctorOp(functor));
87cd1c3eba69d044b551cededad75474038f919890John Reck    mDisplayList->functors.push_back({functor, listener});
88cd1c3eba69d044b551cededad75474038f919890John Reck    mDisplayList->ref(listener);
89daf98e941e140e8739458126640183b9f296a2abChet Haase}
90daf98e941e140e8739458126640183b9f296a2abChet Haase
91db663fe83f976107fd8fd9307d871b37d9e47370Chris CraikSkCanvas* DisplayListCanvas::asSkCanvas() {
92003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    LOG_ALWAYS_FATAL_IF(!mDisplayList,
931db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger            "attempting to get an SkCanvas when we are not recording!");
941db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger    if (!mSkiaCanvasProxy) {
951db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger        mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this));
961db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger    }
9790fb1f6732a610ad5ff6acdb3bd9ae392c8eac82Tom Hudson
9890fb1f6732a610ad5ff6acdb3bd9ae392c8eac82Tom Hudson    // SkCanvas instances default to identity transform, but should inherit
9990fb1f6732a610ad5ff6acdb3bd9ae392c8eac82Tom Hudson    // the state of this Canvas; if this code was in the SkiaCanvasProxy
10090fb1f6732a610ad5ff6acdb3bd9ae392c8eac82Tom Hudson    // constructor, we couldn't cache mSkiaCanvasProxy.
10190fb1f6732a610ad5ff6acdb3bd9ae392c8eac82Tom Hudson    SkMatrix parentTransform;
10290fb1f6732a610ad5ff6acdb3bd9ae392c8eac82Tom Hudson    getMatrix(&parentTransform);
10390fb1f6732a610ad5ff6acdb3bd9ae392c8eac82Tom Hudson    mSkiaCanvasProxy.get()->setMatrix(parentTransform);
10490fb1f6732a610ad5ff6acdb3bd9ae392c8eac82Tom Hudson
1051db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger    return mSkiaCanvasProxy.get();
1061db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger}
1071db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger
108eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malitaint DisplayListCanvas::save(SaveFlags::Flags flags) {
1098dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addStateOp(new (alloc()) SaveOp((int) flags));
1108dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    return mState.save((int) flags);
1114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
113db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::restore() {
11404c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy    if (mRestoreSaveCount < 0) {
11533f6beb10f98e8ba96250e284876d607055d278dRomain Guy        restoreToCount(getSaveCount() - 1);
11633f6beb10f98e8ba96250e284876d607055d278dRomain Guy        return;
11704c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy    }
11833f6beb10f98e8ba96250e284876d607055d278dRomain Guy
11933f6beb10f98e8ba96250e284876d607055d278dRomain Guy    mRestoreSaveCount--;
1208afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
121984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    mState.restore();
1224aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1234aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
124db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::restoreToCount(int saveCount) {
12527454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    mRestoreSaveCount = saveCount;
1268afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
127984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    mState.restoreToCount(saveCount);
1284aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1294aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
130db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikint DisplayListCanvas::saveLayer(float left, float top, float right, float bottom,
131eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita        const SkPaint* paint, SaveFlags::Flags flags) {
1324ace7305608442ab35ea9aa65a4220df152c187fChris Craik    // force matrix/clip isolation for layer
133eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita    flags |= SaveFlags::MatrixClip;
1344ace7305608442ab35ea9aa65a4220df152c187fChris Craik
135d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger    paint = refPaint(paint);
1368dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags));
1378dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    return mState.save((int) flags);
1385b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
1395b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
140db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::translate(float dx, float dy) {
141772687d24206e2fa2deebf0980a932573a624b17Chris Craik    if (dx == 0.0f && dy == 0.0f) return;
142772687d24206e2fa2deebf0980a932573a624b17Chris Craik
1438afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    mHasDeferredTranslate = true;
14433f6beb10f98e8ba96250e284876d607055d278dRomain Guy    mTranslateX += dx;
14533f6beb10f98e8ba96250e284876d607055d278dRomain Guy    mTranslateY += dy;
1468afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushRestoreToCount();
1478dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    mState.translate(dx, dy, 0.0f);
1484aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1494aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
150db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::rotate(float degrees) {
151772687d24206e2fa2deebf0980a932573a624b17Chris Craik    if (degrees == 0.0f) return;
152772687d24206e2fa2deebf0980a932573a624b17Chris Craik
1532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) RotateOp(degrees));
154984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    mState.rotate(degrees);
1554aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1564aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
157db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::scale(float sx, float sy) {
158772687d24206e2fa2deebf0980a932573a624b17Chris Craik    if (sx == 1.0f && sy == 1.0f) return;
159772687d24206e2fa2deebf0980a932573a624b17Chris Craik
1602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ScaleOp(sx, sy));
161984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    mState.scale(sx, sy);
1624aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1634aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
164db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::skew(float sx, float sy) {
1652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) SkewOp(sx, sy));
166984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    mState.skew(sx, sy);
167807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy}
168807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy
169db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::setMatrix(const SkMatrix& matrix) {
1702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) SetMatrixOp(matrix));
171984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    mState.setMatrix(matrix);
1724aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1734aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
174db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::concat(const SkMatrix& matrix) {
1752af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ConcatMatrixOp(matrix));
176984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    mState.concatMatrix(matrix);
1774aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1784aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
179db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::getClipBounds(SkRect* outRect) const {
1808dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    Rect bounds = mState.getLocalClipBounds();
1818dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom);
1828dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    return !(outRect->isEmpty());
1838dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson}
1848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
185db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::quickRejectRect(float left, float top, float right, float bottom) const {
1868dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    return mState.quickRejectConservative(left, top, right, bottom);
1878dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson}
1888dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
189db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::quickRejectPath(const SkPath& path) const {
1908dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    SkRect bounds = path.getBounds();
1918dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
1928dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson}
1938dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1948dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
195db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipRect(float left, float top, float right, float bottom,
1964aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        SkRegion::Op op) {
1972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
198984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    return mState.clipRect(left, top, right, bottom, op);
1994aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
2004aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
201db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipPath(const SkPath* path, SkRegion::Op op) {
2022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    path = refPath(path);
2032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ClipPathOp(path, op));
204984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    return mState.clipPath(path, op);
205735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy}
206735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
207db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikbool DisplayListCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
2082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    region = refRegion(region);
2092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ClipRegionOp(region, op));
210984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    return mState.clipRegion(region, op);
211735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy}
212735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
213956f340aacc7d8fc2d10f776551f13fde2d8d3abChris Craikvoid DisplayListCanvas::drawRenderNode(RenderNode* renderNode) {
2148afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");
215a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik    DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(
216a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik            renderNode,
217a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik            *mState.currentTransform(),
218a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik            mState.clipIsSimple());
2198afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    addRenderNodeOp(op);
2200fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy}
2210fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy
2223aadd60521960be063ee06208562ccb63dc414e3Chris Craikvoid DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle) {
22312f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck    // We ref the DeferredLayerUpdater due to its thread-safe ref-counting
22412f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck    // semantics.
225003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(layerHandle);
2263aadd60521960be063ee06208562ccb63dc414e3Chris Craik    addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer()));
2276c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}
2286c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
229db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
2307c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    bitmap = refBitmap(*bitmap);
2312af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
2322af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
233796475006f5d670e8383a2050f11719522437a43Chris Craik    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint));
2344aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
2354aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
236db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top,
2378dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        const SkPaint* paint) {
238eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita    save(SaveFlags::Matrix);
2398dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    translate(left, top);
2408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    drawBitmap(&bitmap, paint);
2418dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    restore();
2428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson}
2438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
244db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
2458dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        const SkPaint* paint) {
2468dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    if (matrix.isIdentity()) {
2478dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        drawBitmap(&bitmap, paint);
248e688bf720334f58e0003b4c75b53cc7618adf43fChris Craik    } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))
249e688bf720334f58e0003b4c75b53cc7618adf43fChris Craik            && MathUtils::isPositive(matrix.getScaleX())
250e688bf720334f58e0003b4c75b53cc7618adf43fChris Craik            && MathUtils::isPositive(matrix.getScaleY())) {
2518dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        // SkMatrix::isScaleTranslate() not available in L
2528dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        SkRect src;
2538dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        SkRect dst;
2548dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        bitmap.getBounds(&src);
2558dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        matrix.mapRect(&dst, src);
2568dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
2578dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson                   dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
2588dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    } else {
259eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita        save(SaveFlags::Matrix);
2608dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        concat(matrix);
2618dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        drawBitmap(&bitmap, paint);
2628dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        restore();
2638dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    }
2648dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson}
2658dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
266db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
2674aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        float srcRight, float srcBottom, float dstLeft, float dstTop,
268d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        float dstRight, float dstBottom, const SkPaint* paint) {
269796475006f5d670e8383a2050f11719522437a43Chris Craik    if (srcLeft == 0 && srcTop == 0
27014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik            && srcRight == bitmap.width()
27114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik            && srcBottom == bitmap.height()
272796475006f5d670e8383a2050f11719522437a43Chris Craik            && (srcBottom - srcTop == dstBottom - dstTop)
273796475006f5d670e8383a2050f11719522437a43Chris Craik            && (srcRight - srcLeft == dstRight - dstLeft)) {
274527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik        // transform simple rect to rect drawing case into position bitmap ops, since they merge
275eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita        save(SaveFlags::Matrix);
276796475006f5d670e8383a2050f11719522437a43Chris Craik        translate(dstLeft, dstTop);
2778dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        drawBitmap(&bitmap, paint);
278796475006f5d670e8383a2050f11719522437a43Chris Craik        restore();
279796475006f5d670e8383a2050f11719522437a43Chris Craik    } else {
280796475006f5d670e8383a2050f11719522437a43Chris Craik        paint = refPaint(paint);
281796475006f5d670e8383a2050f11719522437a43Chris Craik
28214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik        if (paint && paint->getShader()) {
28314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik            float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft);
28414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik            float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop);
28514100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik            if (!MathUtils::areEqual(scaleX, 1.0f) || !MathUtils::areEqual(scaleY, 1.0f)) {
28614100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                // Apply the scale transform on the canvas, so that the shader
28714100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                // effectively calculates positions relative to src rect space
28814100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik
289eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita                save(SaveFlags::Matrix);
29014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                translate(dstLeft, dstTop);
29114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                scale(scaleX, scaleY);
29214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik
29314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                dstLeft = 0.0f;
29414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                dstTop = 0.0f;
29514100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                dstRight = srcRight - srcLeft;
29614100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                dstBottom = srcBottom - srcTop;
29714100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik
2987c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck                addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(bitmap),
29914100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                        srcLeft, srcTop, srcRight, srcBottom,
30014100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                        dstLeft, dstTop, dstRight, dstBottom, paint));
30114100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                restore();
30214100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik                return;
30314100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik            }
30414100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik        }
30514100ac9f8efc1a2407e3f5a5c8b2532a49585dbChris Craik
3067c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck        addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(bitmap),
307796475006f5d670e8383a2050f11719522437a43Chris Craik                srcLeft, srcTop, srcRight, srcBottom,
308796475006f5d670e8383a2050f11719522437a43Chris Craik                dstLeft, dstTop, dstRight, dstBottom, paint));
309527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik    }
3104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
3114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
312db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
313d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        const float* vertices, const int* colors, const SkPaint* paint) {
3140664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik    int vertexCount = (meshWidth + 1) * (meshHeight + 1);
3150664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik    vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex
3162af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3170664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik    colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex
3182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3197c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    addDrawOp(new (alloc()) DrawBitmapMeshOp(refBitmap(bitmap), meshWidth, meshHeight,
3208dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson           vertices, colors, paint));
3215a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy}
3225a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
3234c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenbergervoid DisplayListCanvas::drawNinePatch(const SkBitmap& bitmap, const Res_png_9patch& patch,
3244c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
3257c103a36f60b690e3fe83c40210e1cb0c76bba43John Reck    const SkBitmap* bitmapPtr = refBitmap(bitmap);
3264c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    const Res_png_9patch* patchPtr = refPatch(&patch);
32716ea8d373b03b1e115dd505af70dbee4e3a3a182Romain Guy    paint = refPaint(paint);
3282af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3294c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    addDrawOp(new (alloc()) DrawPatchOp(bitmapPtr, patchPtr,
3304c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger            dstLeft, dstTop, dstRight, dstBottom, paint));
3314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
3324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
333db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawColor(int color, SkXfermode::Mode mode) {
3342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawColorOp(color, mode));
3354aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
3364aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
337db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPaint(const SkPaint& paint) {
3388dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    SkRect bounds;
3398dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    if (getClipBounds(&bounds)) {
3408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint);
3418dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    }
3428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson}
3438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
3448dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
345db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRect(float left, float top, float right, float bottom,
3468dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        const SkPaint& paint) {
3478dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, refPaint(&paint)));
3484aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
3494aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
350db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRoundRect(float left, float top, float right, float bottom,
3518dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        float rx, float ry, const SkPaint& paint) {
3528dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, refPaint(&paint)));
35301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
35401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
355db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRoundRect(
356072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
357072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
358072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
359072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        CanvasPropertyPaint* paint) {
360003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(left);
361003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(top);
362003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(right);
363003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(bottom);
364003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(rx);
365003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(ry);
366003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(paint);
36737b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    refBitmapsInShader(paint->value.getShader());
368072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
369072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            &right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
370072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi}
371072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi
372db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
3738dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, refPaint(&paint)));
37401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
37501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
376db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
37752244fff29042926e21fa897ef5ab11148e35299John Reck        CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
378003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(x);
379003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(y);
380003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(radius);
381003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ref(paint);
38237b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    refBitmapsInShader(paint->value.getShader());
38352244fff29042926e21fa897ef5ab11148e35299John Reck    addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value,
38452244fff29042926e21fa897ef5ab11148e35299John Reck            &radius->value, &paint->value));
38552244fff29042926e21fa897ef5ab11148e35299John Reck}
38652244fff29042926e21fa897ef5ab11148e35299John Reck
387db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawOval(float left, float top, float right, float bottom,
3888dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        const SkPaint& paint) {
3898dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, refPaint(&paint)));
390c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}
391c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
392db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawArc(float left, float top, float right, float bottom,
3938dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
394544e524db6e4da526af1c897fe5314036ede5012Chris Craik    if (fabs(sweepAngle) >= 360.0f) {
395107843de4507b3511006cb9c77b8d0364374385aTom Hudson        drawOval(left, top, right, bottom, paint);
396107843de4507b3511006cb9c77b8d0364374385aTom Hudson    } else {
397107843de4507b3511006cb9c77b8d0364374385aTom Hudson        addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
3988dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson                        startAngle, sweepAngle, useCenter, refPaint(&paint)));
3996ac174b97246ed40fe780b29561603b61770fa17Chris Craik    }
4008b2f5267f16c295f12faab810527cd6311997e34Romain Guy}
4018b2f5267f16c295f12faab810527cd6311997e34Romain Guy
402db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
4038dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addDrawOp(new (alloc()) DrawPathOp(refPath(&path), refPaint(&paint)));
4044aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
4054aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
406db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawLines(const float* points, int count, const SkPaint& paint) {
4072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    points = refBuffer<float>(points, count);
4082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4098dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addDrawOp(new (alloc()) DrawLinesOp(points, count, refPaint(&paint)));
410ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy}
411ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy
412db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawPoints(const float* points, int count, const SkPaint& paint) {
4132af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    points = refBuffer<float>(points, count);
4142af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4158dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    addDrawOp(new (alloc()) DrawPointsOp(points, count, refPaint(&paint)));
4164aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
4174aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
418766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid DisplayListCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
419766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu    mDisplayList->ref(tree);
4201d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    mDisplayList->pushStagingFunctors.push_back(tree->getFunctor());
4211d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    addDrawOp(new (alloc()) DrawVectorDrawableOp(tree, tree->stagingProperties()->getBounds()));
422766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu}
423766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu
424dccca44ffda4836b56a21da95a046c9708ffd49csergeyvvoid DisplayListCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int count,
4258dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) {
4268dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    if (!glyphs || count <= 0) return;
4272af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4288dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    int bytesCount = 2 * count;
429e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    DrawOp* op = new (alloc()) DrawTextOnPathOp(refBuffer<glyph_t>(glyphs, count),
4308dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            bytesCount, count, refPath(&path),
4318dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            hOffset, vOffset, refPaint(&paint));
4320f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    addDrawOp(op);
433996e57c84368058be793897ebc355b917a59abc2Raph Levien}
434996e57c84368058be793897ebc355b917a59abc2Raph Levien
435dccca44ffda4836b56a21da95a046c9708ffd49csergeyvvoid DisplayListCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions,
4368dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        int count, const SkPaint& paint, float x, float y,
4378dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
4388dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        float totalAdvance) {
439527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik
4408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
44133f6beb10f98e8ba96250e284876d607055d278dRomain Guy
4428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    int bytesCount = count * 2;
4432af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    positions = refBuffer<float>(positions, count * 2);
4448dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom);
44533f6beb10f98e8ba96250e284876d607055d278dRomain Guy
446e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    DrawOp* op = new (alloc()) DrawTextOp(refBuffer<glyph_t>(glyphs, count), bytesCount, count,
4476578a989566e585eee053095dc80e2552e125db2Derek Sollenberger            x, y, positions, refPaint(&paint), totalAdvance, bounds);
4486578a989566e585eee053095dc80e2552e125db2Derek Sollenberger    addDrawOp(op);
449a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik    drawTextDecorations(x, y, totalAdvance, paint);
450672433d90fab7383cd28beac9d4485b566a90940Romain Guy}
451672433d90fab7383cd28beac9d4485b566a90940Romain Guy
45294394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenbergervoid DisplayListCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
45394394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    if (paint.getStyle() != SkPaint::kFill_Style ||
45494394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            (paint.isAntiAlias() && !mState.currentTransform()->isSimple())) {
45594394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        SkRegion::Iterator it(region);
45694394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        while (!it.done()) {
45794394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            const SkIRect& r = it.rect();
45894394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
45994394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            it.next();
46094394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        }
46194394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    } else {
46294394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        int count = 0;
46394394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        Vector<float> rects;
46494394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        SkRegion::Iterator it(region);
46594394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        while (!it.done()) {
46694394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            const SkIRect& r = it.rect();
46794394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            rects.push(r.fLeft);
46894394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            rects.push(r.fTop);
46994394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            rects.push(r.fRight);
47094394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            rects.push(r.fBottom);
47194394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            count += 4;
47294394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger            it.next();
47394394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        }
47494394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger        drawRects(rects.array(), count, &paint);
47594394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger    }
47694394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger}
47794394b3fb048d5349a77b57950ab7f6b6e92ce34Derek Sollenberger
478db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::drawRects(const float* rects, int count, const SkPaint* paint) {
479107843de4507b3511006cb9c77b8d0364374385aTom Hudson    if (count <= 0) return;
480672433d90fab7383cd28beac9d4485b566a90940Romain Guy
4812af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    rects = refBuffer<float>(rects, count);
4822af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
4832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
484eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy}
485eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
486db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::setDrawFilter(SkDrawFilter* filter) {
4870b8606266c1afc69cbeb73acda67c85d87943318Derek Sollenberger    mDrawFilter.reset(SkSafeRef(filter));
4882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
4892af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
490db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::insertReorderBarrier(bool enableReorder) {
4918afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushRestoreToCount();
4928afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
4938afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    mDeferredBarrierType = enableReorder ? kBarrier_OutOfOrder : kBarrier_InOrder;
4948afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
4958afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
496db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::flushRestoreToCount() {
4972af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (mRestoreSaveCount >= 0) {
4988afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        addOpAndUpdateChunk(new (alloc()) RestoreToCountOp(mRestoreSaveCount));
4992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        mRestoreSaveCount = -1;
5002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
5012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
5022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
503db663fe83f976107fd8fd9307d871b37d9e47370Chris Craikvoid DisplayListCanvas::flushTranslate() {
5048afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    if (mHasDeferredTranslate) {
5052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
5068afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik            addOpAndUpdateChunk(new (alloc()) TranslateOp(mTranslateX, mTranslateY));
5072af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            mTranslateX = mTranslateY = 0.0f;
5082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        }
5098afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        mHasDeferredTranslate = false;
5102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
5112af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
5122af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
513db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) {
514003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    int insertIndex = mDisplayList->ops.size();
51510ed692118552a01ff97b095295852b631e51beeChris Craik#if HWUI_NEW_OPS
51610ed692118552a01ff97b095295852b631e51beeChris Craik    LOG_ALWAYS_FATAL("unsupported");
51710ed692118552a01ff97b095295852b631e51beeChris Craik#else
518003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->ops.push_back(op);
51910ed692118552a01ff97b095295852b631e51beeChris Craik#endif
5208afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    if (mDeferredBarrierType != kBarrier_None) {
5218afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        // op is first in new chunk
522003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik        mDisplayList->chunks.emplace_back();
523003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik        DisplayList::Chunk& newChunk = mDisplayList->chunks.back();
5248afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        newChunk.beginOpIndex = insertIndex;
5258afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        newChunk.endOpIndex = insertIndex + 1;
5268afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder);
5278afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
528b36af87f8275f4b982906f88193ec27600f2746aChris Craik        int nextChildIndex = mDisplayList->children.size();
5298afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex;
5308afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        mDeferredBarrierType = kBarrier_None;
5318afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    } else {
5328afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        // standard case - append to existing chunk
533003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik        mDisplayList->chunks.back().endOpIndex = insertIndex + 1;
5348afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
5358afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return insertIndex;
5362af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
5372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
538db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::flushAndAddOp(DisplayListOp* op) {
5398afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushRestoreToCount();
5408afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
5418afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return addOpAndUpdateChunk(op);
5428afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
5438afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
544db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addStateOp(StateOp* op) {
5458afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return flushAndAddOp(op);
5468afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
5478afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
548db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addDrawOp(DrawOp* op) {
5492af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    Rect localBounds;
5503b20251a355c88193c439f928a84ae69483fb488John Reck    if (op->getLocalBounds(localBounds)) {
5518dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        bool rejected = quickRejectRect(localBounds.left, localBounds.top,
5522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                localBounds.right, localBounds.bottom);
5532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        op->setQuickRejected(rejected);
5542af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
555c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik
556003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    mDisplayList->hasDrawOps = true;
5578afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return flushAndAddOp(op);
5588afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
5598afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
560db663fe83f976107fd8fd9307d871b37d9e47370Chris Craiksize_t DisplayListCanvas::addRenderNodeOp(DrawRenderNodeOp* op) {
5618afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    int opIndex = addDrawOp(op);
562b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#if !HWUI_NEW_OPS
563003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    int childIndex = mDisplayList->addChild(op);
5648afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
5658afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    // update the chunk's child indices
566003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik    DisplayList::Chunk& chunk = mDisplayList->chunks.back();
5678afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    chunk.endChildIndex = childIndex + 1;
5688afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
569b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    if (op->renderNode->stagingProperties().isProjectionReceiver()) {
5708afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        // use staging property, since recording on UI thread
571003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik        mDisplayList->projectionReceiveIndex = opIndex;
5728afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
573b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif
5748afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return opIndex;
5755ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy}
5765ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy
57737b0824a46157b7e169ad7ec33a46e89c851884cJohn Reckvoid DisplayListCanvas::refBitmapsInShader(const SkShader* shader) {
57837b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    if (!shader) return;
57937b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck
58037b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    // If this paint has an SkShader that has an SkBitmap add
58137b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    // it to the bitmap pile
58237b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    SkBitmap bitmap;
58337b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    SkShader::TileMode xy[2];
584f35b989d26bb98900f6c5fa2e586326b30b6e161Leon Scroggins III    if (shader->isABitmap(&bitmap, nullptr, xy)) {
58537b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck        refBitmap(bitmap);
58637b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck        return;
58737b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    }
58837b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    SkShader::ComposeRec rec;
58937b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    if (shader->asACompose(&rec)) {
59037b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck        refBitmapsInShader(rec.fShaderA);
59137b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck        refBitmapsInShader(rec.fShaderB);
59237b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck        return;
59337b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck    }
59437b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck}
59537b0824a46157b7e169ad7ec33a46e89c851884cJohn Reck
5964aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace uirenderer
5974aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace android
598