DisplayListCanvas.cpp revision e8c3c813b0e3ac98304b17a751ce6e436e252bd9
1093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber/*
2093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Copyright (C) 2010 The Android Open Source Project
3093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *
4093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * you may not use this file except in compliance with the License.
6093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * You may obtain a copy of the License at
7093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *
8093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *
10093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Unless required by applicable law or agreed to in writing, software
11093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * See the License for the specific language governing permissions and
14093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * limitations under the License.
15093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber */
16093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
17093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "DisplayListCanvas.h"
18093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
19093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "DeferredDisplayList.h"
20093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "DeferredLayerUpdater.h"
21093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "DisplayListOp.h"
22093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "ResourceCache.h"
23b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include "RenderNode.h"
242dcf6138ebc9c5688aeae151d2fbde55a2826128Robert Shih#include "VectorDrawable.h"
25b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include "utils/PaintUtils.h"
26093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
27093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <SkCamera.h>
28093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <SkCanvas.h>
29093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
30093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <private/hwui/DrawGlInfo.h>
31093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
32b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Hubernamespace android {
33093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubernamespace uirenderer {
34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
35b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin CrossDisplayListCanvas::DisplayListCanvas(int width, int height)
36b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    : mState(*this)
37093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    , mResourceCache(ResourceCache::getInstance())
38093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    , mDisplayList(nullptr)
39093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    , mTranslateX(0.0f)
40093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    , mTranslateY(0.0f)
41093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    , mHasDeferredTranslate(false)
42093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    , mDeferredBarrierType(kBarrier_None)
43093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    , mHighContrastText(false)
44093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    , mRestoreSaveCount(-1) {
45093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    resetRecording(width, height);
46093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
47093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
48093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberDisplayListCanvas::~DisplayListCanvas() {
49093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    LOG_ALWAYS_FATAL_IF(mDisplayList,
50093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            "Destroyed a DisplayListCanvas during a record!");
51093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
52093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
53093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::resetRecording(int width, int height) {
54093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    LOG_ALWAYS_FATAL_IF(mDisplayList,
55093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            "prepareDirty called a second time during a recording!");
56093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mDisplayList = new DisplayList();
57093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
58093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mState.initializeSaveStack(width, height,
59093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            0, 0, width, height, Vector3());
60093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
61093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mDeferredBarrierType = kBarrier_InOrder;
62c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    mState.setDirtyClip(false);
63093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mRestoreSaveCount = -1;
64d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
65d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
66d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
67d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber///////////////////////////////////////////////////////////////////////////////
68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber// Operations
69093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber///////////////////////////////////////////////////////////////////////////////
70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
71093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberDisplayList* DisplayListCanvas::finishRecording() {
72093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    flushRestoreToCount();
73093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    flushTranslate();
74093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mPaintMap.clear();
76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mRegionMap.clear();
77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mPathMap.clear();
78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DisplayList* displayList = mDisplayList;
79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mDisplayList = nullptr;
80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mSkiaCanvasProxy.reset(nullptr);
81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return displayList;
82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::callDrawGLFunction(Functor *functor) {
85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    addDrawOp(new (alloc()) DrawFunctorOp(functor));
86093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mDisplayList->functors.push_back(functor);
87093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
88093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
89093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberSkCanvas* DisplayListCanvas::asSkCanvas() {
905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    LOG_ALWAYS_FATAL_IF(!mDisplayList,
912f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            "attempting to get an SkCanvas when we are not recording!");
925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    if (!mSkiaCanvasProxy) {
935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this));
945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    // SkCanvas instances default to identity transform, but should inherit
975ec58d925520e6913fba3fc54413881af751c610Andreas Huber    // the state of this Canvas; if this code was in the SkiaCanvasProxy
985ec58d925520e6913fba3fc54413881af751c610Andreas Huber    // constructor, we couldn't cache mSkiaCanvasProxy.
99f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann    SkMatrix parentTransform;
1005ec58d925520e6913fba3fc54413881af751c610Andreas Huber    getMatrix(&parentTransform);
1015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mSkiaCanvasProxy.get()->setMatrix(parentTransform);
1025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
1035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mSkiaCanvasProxy.get();
1045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
1055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
106d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberint DisplayListCanvas::save(SaveFlags::Flags flags) {
107b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    addStateOp(new (alloc()) SaveOp((int) flags));
1082f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    return mState.save((int) flags);
1095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
110d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
1115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid DisplayListCanvas::restore() {
112d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (mRestoreSaveCount < 0) {
113d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        restoreToCount(getSaveCount() - 1);
114d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        return;
1155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
1165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
1175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mRestoreSaveCount--;
1185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    flushTranslate();
1195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mState.restore();
120093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
121093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
122093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::restoreToCount(int saveCount) {
123093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mRestoreSaveCount = saveCount;
124093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    flushTranslate();
125093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mState.restoreToCount(saveCount);
126093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
127093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
128093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberint DisplayListCanvas::saveLayer(float left, float top, float right, float bottom,
129093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const SkPaint* paint, SaveFlags::Flags flags) {
130093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // force matrix/clip isolation for layer
131093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    flags |= SaveFlags::MatrixClip;
13250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
13350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    paint = refPaint(paint);
13450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags));
135093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mState.save((int) flags);
136093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
137093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
138093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::translate(float dx, float dy) {
139093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (dx == 0.0f && dy == 0.0f) return;
140093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
141093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mHasDeferredTranslate = true;
142093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mTranslateX += dx;
143093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mTranslateY += dy;
144093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    flushRestoreToCount();
14574a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    mState.translate(dx, dy, 0.0f);
1465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
147b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
148093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::rotate(float degrees) {
14950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (degrees == 0.0f) return;
15050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    addStateOp(new (alloc()) RotateOp(degrees));
152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mState.rotate(degrees);
153793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih}
15450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
15550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid DisplayListCanvas::scale(float sx, float sy) {
15650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (sx == 1.0f && sy == 1.0f) return;
157093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    addStateOp(new (alloc()) ScaleOp(sx, sy));
159093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mState.scale(sx, sy);
160093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
1612f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1622f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihvoid DisplayListCanvas::skew(float sx, float sy) {
1632f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    addStateOp(new (alloc()) SkewOp(sx, sy));
1642f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    mState.skew(sx, sy);
1652f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
1662f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1672f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihvoid DisplayListCanvas::setMatrix(const SkMatrix& matrix) {
1682f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    addStateOp(new (alloc()) SetMatrixOp(matrix));
1692f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    mState.setMatrix(matrix);
1702f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
1712f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1722f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihvoid DisplayListCanvas::concat(const SkMatrix& matrix) {
1732f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    addStateOp(new (alloc()) ConcatMatrixOp(matrix));
1742f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    mState.concatMatrix(matrix);
1752f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
1762f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1772f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihbool DisplayListCanvas::getClipBounds(SkRect* outRect) const {
1782f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    Rect bounds = mState.getLocalClipBounds();
1792f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom);
1802f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    return !(outRect->isEmpty());
1812f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
1822f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1832f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihbool DisplayListCanvas::quickRejectRect(float left, float top, float right, float bottom) const {
1842f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    return mState.quickRejectConservative(left, top, right, bottom);
1852f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
1862f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1872f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihbool DisplayListCanvas::quickRejectPath(const SkPath& path) const {
1882f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    SkRect bounds = path.getBounds();
1892f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
1902f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
1912f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1922f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1932f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihbool DisplayListCanvas::clipRect(float left, float top, float right, float bottom,
1942f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        SkRegion::Op op) {
1952f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
1962f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    return mState.clipRect(left, top, right, bottom, op);
1972f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
1982f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
1992f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihbool DisplayListCanvas::clipPath(const SkPath* path, SkRegion::Op op) {
2002f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    path = refPath(path);
2012f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    addStateOp(new (alloc()) ClipPathOp(path, op));
2022f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    return mState.clipPath(path, op);
2032f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
2042f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
2052f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihbool DisplayListCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
2062f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    region = refRegion(region);
2072f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    addStateOp(new (alloc()) ClipRegionOp(region, op));
208093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mState.clipRegion(region, op);
209093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
210093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
211093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::drawRenderNode(RenderNode* renderNode) {
212093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");
21374a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(
214d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            renderNode,
2152f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            *mState.currentTransform(),
2162f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            mState.clipIsSimple());
217b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    addRenderNodeOp(op);
218b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber}
219b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
220093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle) {
221b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    // We ref the DeferredLayerUpdater due to its thread-safe ref-counting
222093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // semantics.
22374a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    mDisplayList->ref(layerHandle);
22474a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer()));
225093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
226093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
227b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Hubervoid DisplayListCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
228b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    bitmap = refBitmap(*bitmap);
229b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    paint = refPaint(paint);
230b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
231b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint));
232b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber}
233b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
234b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Hubervoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top,
235b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        const SkPaint* paint) {
236b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    save(SaveFlags::Matrix);
237b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    translate(left, top);
238093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    drawBitmap(&bitmap, paint);
239093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    restore();
240093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
241093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
242093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
24350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        const SkPaint* paint) {
24450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (matrix.isIdentity()) {
24550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        drawBitmap(&bitmap, paint);
24650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))
24784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber            && MathUtils::isPositive(matrix.getScaleX())
2485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            && MathUtils::isPositive(matrix.getScaleY())) {
249093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        // SkMatrix::isScaleTranslate() not available in L
250093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        SkRect src;
251093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        SkRect dst;
252093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        bitmap.getBounds(&src);
253093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        matrix.mapRect(&dst, src);
25450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
25550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                   dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
256093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    } else {
257093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        save(SaveFlags::Matrix);
258093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        concat(matrix);
259093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        drawBitmap(&bitmap, paint);
260093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        restore();
261093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
262093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
2635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
2655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        float srcRight, float srcBottom, float dstLeft, float dstTop,
2662f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        float dstRight, float dstBottom, const SkPaint* paint) {
267d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (srcLeft == 0 && srcTop == 0
2685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            && srcRight == bitmap.width()
2692f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            && srcBottom == bitmap.height()
2705279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            && (srcBottom - srcTop == dstBottom - dstTop)
271d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            && (srcRight - srcLeft == dstRight - dstLeft)) {
272d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        // transform simple rect to rect drawing case into position bitmap ops, since they merge
2735279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        save(SaveFlags::Matrix);
2745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        translate(dstLeft, dstTop);
2755279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        drawBitmap(&bitmap, paint);
2765279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        restore();
2775279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    } else {
2785279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        paint = refPaint(paint);
2795279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2805279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (paint && paint->getShader()) {
281d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft);
282d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop);
283d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            if (!MathUtils::areEqual(scaleX, 1.0f) || !MathUtils::areEqual(scaleY, 1.0f)) {
284d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                // Apply the scale transform on the canvas, so that the shader
285d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                // effectively calculates positions relative to src rect space
286d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
287d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                save(SaveFlags::Matrix);
2883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                translate(dstLeft, dstTop);
289d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                scale(scaleX, scaleY);
290d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
291d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                dstLeft = 0.0f;
292d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                dstTop = 0.0f;
293d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                dstRight = srcRight - srcLeft;
294d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                dstBottom = srcBottom - srcTop;
295d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
296d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(bitmap),
297d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                        srcLeft, srcTop, srcRight, srcBottom,
2983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                        dstLeft, dstTop, dstRight, dstBottom, paint));
299d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                restore();
300d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                return;
301d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            }
302d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        }
30329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
3045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(bitmap),
305d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                srcLeft, srcTop, srcRight, srcBottom,
3065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                dstLeft, dstTop, dstRight, dstBottom, paint));
307093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
3085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
309d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
310d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid DisplayListCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
311d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        const float* vertices, const int* colors, const SkPaint* paint) {
312d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    int vertexCount = (meshWidth + 1) * (meshHeight + 1);
313d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex
314d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    paint = refPaint(paint);
315d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex
3163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
317d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    addDrawOp(new (alloc()) DrawBitmapMeshOp(refBitmap(bitmap), meshWidth, meshHeight,
318e467ef084b75b074d0081616080b54212a7024c8Lajos Molnar           vertices, colors, paint));
319e467ef084b75b074d0081616080b54212a7024c8Lajos Molnar}
320d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
321d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid DisplayListCanvas::drawNinePatch(const SkBitmap& bitmap, const Res_png_9patch& patch,
322d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
323d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    const SkBitmap* bitmapPtr = refBitmap(bitmap);
324d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    const Res_png_9patch* patchPtr = refPatch(&patch);
325d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    paint = refPaint(paint);
326d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
327d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    addDrawOp(new (alloc()) DrawPatchOp(bitmapPtr, patchPtr,
328d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            dstLeft, dstTop, dstRight, dstBottom, paint));
329d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
330d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
331d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid DisplayListCanvas::drawColor(int color, SkXfermode::Mode mode) {
3323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    addDrawOp(new (alloc()) DrawColorOp(color, mode));
333d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
334d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
335d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid DisplayListCanvas::drawPaint(const SkPaint& paint) {
336d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    SkRect bounds;
337093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (getClipBounds(&bounds)) {
338093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint);
339d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    }
340d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
341d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
342d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
343d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid DisplayListCanvas::drawRect(float left, float top, float right, float bottom,
3445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        const SkPaint& paint) {
345093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, refPaint(&paint)));
3465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
3475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid DisplayListCanvas::drawRoundRect(float left, float top, float right, float bottom,
3495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        float rx, float ry, const SkPaint& paint) {
350d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, refPaint(&paint)));
351093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
352d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
3532ba7ce928b0fa8917ee202836b0963ca58613453Andreas Hubervoid DisplayListCanvas::drawRoundRect(
354d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
355d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
356d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
357d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CanvasPropertyPaint* paint) {
358d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mDisplayList->ref(left);
3595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mDisplayList->ref(top);
360093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mDisplayList->ref(right);
3615ec58d925520e6913fba3fc54413881af751c610Andreas Huber    mDisplayList->ref(bottom);
362f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann    mDisplayList->ref(rx);
3635ec58d925520e6913fba3fc54413881af751c610Andreas Huber    mDisplayList->ref(ry);
364d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mDisplayList->ref(paint);
365d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    refBitmapsInShader(paint->value.getShader());
3665ec58d925520e6913fba3fc54413881af751c610Andreas Huber    addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
3675ec58d925520e6913fba3fc54413881af751c610Andreas Huber            &right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
368bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian}
36910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
37010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
37110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, refPaint(&paint)));
37210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann}
37310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
37410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
375b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross        CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
37610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    mDisplayList->ref(x);
37710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    mDisplayList->ref(y);
37810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    mDisplayList->ref(radius);
37910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    mDisplayList->ref(paint);
38010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    refBitmapsInShader(paint->value.getShader());
38110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value,
38210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann            &radius->value, &paint->value));
3835ec58d925520e6913fba3fc54413881af751c610Andreas Huber}
384b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross
38510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawOval(float left, float top, float right, float bottom,
38610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann        const SkPaint& paint) {
38710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, refPaint(&paint)));
38810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann}
38910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
39010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawArc(float left, float top, float right, float bottom,
39110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann        float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
39210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    if (fabs(sweepAngle) >= 360.0f) {
39310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann        drawOval(left, top, right, bottom, paint);
39410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    } else {
39510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann        addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
39610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann                        startAngle, sweepAngle, useCenter, refPaint(&paint)));
39710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    }
39810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann}
39910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
40010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
401be7ac3d682729048af27871311808a76c618abdbJohann    addDrawOp(new (alloc()) DrawPathOp(refPath(&path), refPaint(&paint)));
40210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann}
40310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
40410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawLines(const float* points, int count, const SkPaint& paint) {
40510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    points = refBuffer<float>(points, count);
40610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
40710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    addDrawOp(new (alloc()) DrawLinesOp(points, count, refPaint(&paint)));
40810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann}
40910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
41010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawPoints(const float* points, int count, const SkPaint& paint) {
41110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    points = refBuffer<float>(points, count);
41210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
41310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    addDrawOp(new (alloc()) DrawPointsOp(points, count, refPaint(&paint)));
41410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann}
41510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
41610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
4172f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    mDisplayList->ref(tree);
41810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    const SkBitmap& bitmap = tree->getBitmapUpdateIfDirty();
419be7ac3d682729048af27871311808a76c618abdbJohann    SkPaint* paint = tree->getPaint();
42010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    const SkRect bounds = tree->getBounds();
4212f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(bitmap),
4222f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            0, 0, bitmap.width(), bitmap.height(),
4230644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih            bounds.left(), bounds.top(), bounds.right(), bounds.bottom(), refPaint(paint)));
4242f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
4250644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih
4260644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shihvoid DisplayListCanvas::drawTextOnPath(const uint16_t* glyphs, int count,
4272f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) {
4282f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    if (!glyphs || count <= 0) return;
4292f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
4302f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    int bytesCount = 2 * count;
431be7ac3d682729048af27871311808a76c618abdbJohann    DrawOp* op = new (alloc()) DrawTextOnPathOp(refBuffer<glyph_t>(glyphs, count),
43210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann            bytesCount, count, refPath(&path),
433be7ac3d682729048af27871311808a76c618abdbJohann            hOffset, vOffset, refPaint(&paint));
43410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann    addDrawOp(op);
43510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann}
43610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
43710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions,
4382f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        int count, const SkPaint& paint, float x, float y,
4390644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih        float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
4402f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        float totalAdvance) {
4412f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
4422f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
4432f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
4442f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    int bytesCount = count * 2;
4450644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih    positions = refBuffer<float>(positions, count * 2);
4462f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom);
4472f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
4482f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    DrawOp* op = new (alloc()) DrawTextOp(refBuffer<glyph_t>(glyphs, count), bytesCount, count,
4492f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            x, y, positions, refPaint(&paint), totalAdvance, bounds);
4502f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    addDrawOp(op);
4512f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    drawTextDecorations(x, y, totalAdvance, paint);
45210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann}
45310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann
45410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohannvoid DisplayListCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
4552f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    if (paint.getStyle() != SkPaint::kFill_Style ||
456f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann            (paint.isAntiAlias() && !mState.currentTransform()->isSimple())) {
4572f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        SkRegion::Iterator it(region);
458f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann        while (!it.done()) {
45910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann            const SkIRect& r = it.rect();
46010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann            drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
46110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann            it.next();
46210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann        }
4635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    } else {
464f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann        int count = 0;
465f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann        Vector<float> rects;
466f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann        SkRegion::Iterator it(region);
467f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann        while (!it.done()) {
468f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann            const SkIRect& r = it.rect();
469f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann            rects.push(r.fLeft);
4705ec58d925520e6913fba3fc54413881af751c610Andreas Huber            rects.push(r.fTop);
4715ec58d925520e6913fba3fc54413881af751c610Andreas Huber            rects.push(r.fRight);
472d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            rects.push(r.fBottom);
4735279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            count += 4;
474f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann            it.next();
4755ec58d925520e6913fba3fc54413881af751c610Andreas Huber        }
476f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann        drawRects(rects.array(), count, &paint);
477f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann    }
4782f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
4792f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
4802f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihvoid DisplayListCanvas::drawRects(const float* rects, int count, const SkPaint* paint) {
4812f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    if (count <= 0) return;
4822f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih
4832f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    rects = refBuffer<float>(rects, count);
4842f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    paint = refPaint(paint);
48574a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
4865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
487093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
488093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid DisplayListCanvas::setDrawFilter(SkDrawFilter* filter) {
4895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mDrawFilter.reset(SkSafeRef(filter));
4905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
4915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
4925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid DisplayListCanvas::insertReorderBarrier(bool enableReorder) {
4935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    flushRestoreToCount();
4945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    flushTranslate();
4955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mDeferredBarrierType = enableReorder ? kBarrier_OutOfOrder : kBarrier_InOrder;
4965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
4975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
4985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid DisplayListCanvas::flushRestoreToCount() {
4995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    if (mRestoreSaveCount >= 0) {
5005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        addOpAndUpdateChunk(new (alloc()) RestoreToCountOp(mRestoreSaveCount));
501b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        mRestoreSaveCount = -1;
502b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    }
503b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber}
504b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
50550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid DisplayListCanvas::flushTranslate() {
50650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (mHasDeferredTranslate) {
50750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
50850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            addOpAndUpdateChunk(new (alloc()) TranslateOp(mTranslateX, mTranslateY));
50950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            mTranslateX = mTranslateY = 0.0f;
51050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }
51150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mHasDeferredTranslate = false;
51250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
51350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
51450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
515793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shihsize_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) {
516793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    int insertIndex = mDisplayList->ops.size();
517793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih#if HWUI_NEW_OPS
518793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    LOG_ALWAYS_FATAL("unsupported");
519793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih#else
520793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    mDisplayList->ops.push_back(op);
521793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih#endif
522793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (mDeferredBarrierType != kBarrier_None) {
523793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        // op is first in new chunk
524793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        mDisplayList->chunks.emplace_back();
525793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        DisplayList::Chunk& newChunk = mDisplayList->chunks.back();
526793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        newChunk.beginOpIndex = insertIndex;
527793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        newChunk.endOpIndex = insertIndex + 1;
528793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder);
529793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
530793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        int nextChildIndex = mDisplayList->children.size();
531793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex;
532793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        mDeferredBarrierType = kBarrier_None;
533793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    } else {
534793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        // standard case - append to existing chunk
535793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        mDisplayList->chunks.back().endOpIndex = insertIndex + 1;
536793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
537793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    return insertIndex;
538793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih}
539793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
540793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shihsize_t DisplayListCanvas::flushAndAddOp(DisplayListOp* op) {
541793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    flushRestoreToCount();
542793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    flushTranslate();
543793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    return addOpAndUpdateChunk(op);
544793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih}
545793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
546793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shihsize_t DisplayListCanvas::addStateOp(StateOp* op) {
547793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    return flushAndAddOp(op);
548793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih}
549793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
550793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shihsize_t DisplayListCanvas::addDrawOp(DrawOp* op) {
551793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    Rect localBounds;
552793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (op->getLocalBounds(localBounds)) {
553793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        bool rejected = quickRejectRect(localBounds.left, localBounds.top,
554793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih                localBounds.right, localBounds.bottom);
555793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        op->setQuickRejected(rejected);
556793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
557793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
558793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    mDisplayList->hasDrawOps = true;
559793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    return flushAndAddOp(op);
560793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih}
561793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
562793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shihsize_t DisplayListCanvas::addRenderNodeOp(DrawRenderNodeOp* op) {
563793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    int opIndex = addDrawOp(op);
564793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih#if !HWUI_NEW_OPS
565793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    int childIndex = mDisplayList->addChild(op);
566793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
567793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    // update the chunk's child indices
568793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    DisplayList::Chunk& chunk = mDisplayList->chunks.back();
569793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    chunk.endChildIndex = childIndex + 1;
570793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
571793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (op->renderNode->stagingProperties().isProjectionReceiver()) {
572793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        // use staging property, since recording on UI thread
573793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        mDisplayList->projectionReceiveIndex = opIndex;
574793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
575793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih#endif
576793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    return opIndex;
577793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih}
578793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
579793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shihvoid DisplayListCanvas::refBitmapsInShader(const SkShader* shader) {
580793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (!shader) return;
58150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
58250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // If this paint has an SkShader that has an SkBitmap add
58350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // it to the bitmap pile
5845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    SkBitmap bitmap;
585093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    SkShader::TileMode xy[2];
586093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (shader->isABitmap(&bitmap, nullptr, xy)) {
587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        refBitmap(bitmap);
5885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        return;
58950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
5905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    SkShader::ComposeRec rec;
591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (shader->asACompose(&rec)) {
592d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        refBitmapsInShader(rec.fShaderA);
593d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        refBitmapsInShader(rec.fShaderB);
594b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        return;
595d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    }
596d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
597d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; // namespace uirenderer
599793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih}; // namespace android
600793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih