SkiaCanvas.cpp revision 8dfaa4904205772cdceee63ef3989bcdedf1a914
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
175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2009c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger#include <SkDrawFilter.h>
214aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <SkMatrix.h>
224aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <SkPaint.h>
234aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include <SkPath.h>
242dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include <SkRegion.h>
2509c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger#include <SkTLazy.h>
267953745dd565167113f8cbfc461bc0521d32d870Romain Guy#include <cutils/compiler.h>
277953745dd565167113f8cbfc461bc0521d32d870Romain Guy
288dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson#include <private/graphics/Canvas.h>
298dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
30984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include "CanvasState.h"
312dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "DisplayList.h"
329c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase#include "DisplayListLogBuffer.h"
33984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include "RenderNode.h"
34984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include "Renderer.h"
35a35778c799e8073a42b9e22191bde9d838327ab7John Reck#include "ResourceCache.h"
364aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guynamespace android {
384aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guynamespace uirenderer {
394aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
404aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy///////////////////////////////////////////////////////////////////////////////
414aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy// Defines
424aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy///////////////////////////////////////////////////////////////////////////////
434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
44ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy// Debug
45ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy#if DEBUG_DISPLAY_LIST
465baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__)
47ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy#else
48ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy    #define DISPLAY_LIST_LOGD(...)
49ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy#endif
50ffac7fc5042296a459d0f5a450dbfe20917093dcRomain Guy
514aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy///////////////////////////////////////////////////////////////////////////////
52b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy// Display list
534aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy///////////////////////////////////////////////////////////////////////////////
544aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
55c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craikclass DeferredDisplayList;
5612f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reckclass DeferredLayerUpdater;
57b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guyclass DisplayListRenderer;
582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DisplayListOp;
592dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudsonclass DisplayListRenderer;
602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass DrawOp;
612dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudsonclass RenderNode;
622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craikclass StateOp;
632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
64b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy/**
65d6b65f67717025b1162f86f04e2caa5723566cacChris Craik * Records drawing commands in a display list for later playback into an OpenGLRenderer.
66b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */
678dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudsonclass ANDROID_API DisplayListRenderer: public Canvas, public CanvasStateClient {
68b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guypublic:
693b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer();
707953745dd565167113f8cbfc461bc0521d32d870Romain Guy    virtual ~DisplayListRenderer();
71b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
728afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    void insertReorderBarrier(bool enableReorder);
738afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
743b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListData* finishRecording();
755977baa1fa24125c148a72699b53e62abaf08960Chet Haase
7614e513058ed4168c94e015638d16f5f87fd8063aChris Craik// ----------------------------------------------------------------------------
778dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// HWUI Frame state operations
7814e513058ed4168c94e015638d16f5f87fd8063aChris Craik// ----------------------------------------------------------------------------
798dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
808dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void prepareDirty(float left, float top, float right, float bottom);
818dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void prepare() { prepareDirty(0.0f, 0.0f, width(), height()); }
828dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    bool finish();
838dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void interrupt();
848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void resume();
85daf98e941e140e8739458126640183b9f296a2abChet Haase
8614e513058ed4168c94e015638d16f5f87fd8063aChris Craik// ----------------------------------------------------------------------------
878dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// HWUI Canvas state operations
8814e513058ed4168c94e015638d16f5f87fd8063aChris Craik// ----------------------------------------------------------------------------
89984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
908dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void setViewport(int width, int height) { mState.setViewport(width, height); }
914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
92984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
9314e513058ed4168c94e015638d16f5f87fd8063aChris Craik
943b20251a355c88193c439f928a84ae69483fb488John Reck    bool isCurrentTransformSimple() {
95984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson        return mState.currentTransform()->isSimple();
963b20251a355c88193c439f928a84ae69483fb488John Reck    }
973b20251a355c88193c439f928a84ae69483fb488John Reck
9814e513058ed4168c94e015638d16f5f87fd8063aChris Craik// ----------------------------------------------------------------------------
998dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// HWUI Canvas draw operations
10014e513058ed4168c94e015638d16f5f87fd8063aChris Craik// ----------------------------------------------------------------------------
10114e513058ed4168c94e015638d16f5f87fd8063aChris Craik
10214e513058ed4168c94e015638d16f5f87fd8063aChris Craik    // Bitmap-based
1038dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
1048dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // TODO: move drawBitmapData() to Canvas.h
1058dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
1068dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // TODO: move drawPatch() to Canvas.h
1078dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
1088dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            float left, float top, float right, float bottom, const SkPaint* paint);
10914e513058ed4168c94e015638d16f5f87fd8063aChris Craik
11014e513058ed4168c94e015638d16f5f87fd8063aChris Craik    // Shapes
1118dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void drawRects(const float* rects, int count, const SkPaint* paint);
1128dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
113072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
114072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
115072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi                CanvasPropertyPaint* paint);
1168dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
11752244fff29042926e21fa897ef5ab11148e35299John Reck                CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
11814e513058ed4168c94e015638d16f5f87fd8063aChris Craik
1194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
12014e513058ed4168c94e015638d16f5f87fd8063aChris Craik// ----------------------------------------------------------------------------
1218dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// HWUI Canvas draw operations - special
12214e513058ed4168c94e015638d16f5f87fd8063aChris Craik// ----------------------------------------------------------------------------
1238dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
1248dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags);
1254aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    // TODO: rename for consistency
1278dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    void callDrawGLFunction(Functor* functor, Rect& dirty);
1285ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy
129cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    void setHighContrastText(bool highContrastText) {
130cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        mHighContrastText = highContrastText;
131cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    }
132984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
133984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson// ----------------------------------------------------------------------------
1348dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// CanvasStateClient interface
135984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson// ----------------------------------------------------------------------------
136e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik    virtual void onViewportInitialized() override { }
137e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override { }
138e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik    virtual GLuint onGetTargetFbo() const override { return -1; }
139984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
1408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// ----------------------------------------------------------------------------
1418dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// android/graphics/Canvas interface
1428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// ----------------------------------------------------------------------------
1438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual SkCanvas* getSkCanvas() {
1448dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        LOG_ALWAYS_FATAL("DisplayListRenderer has no SkCanvas");
1458dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        return NULL;
1468dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    }
1478dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void setBitmap(SkBitmap* bitmap, bool copyState) {
1488dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap.");
1498dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    }
1508dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1518dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual bool isOpaque() { return false; }
1528dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual int width() { return mState.getWidth(); }
1538dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual int height() { return mState.getHeight(); }
1548dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1558dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// ----------------------------------------------------------------------------
1568dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// android/graphics/Canvas state operations
1578dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// ----------------------------------------------------------------------------
1588dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // Save (layer)
1598dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual int getSaveCount() const { return mState.getSaveCount(); }
1608dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual int save(SkCanvas::SaveFlags flags);
1618dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void restore();
1628dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void restoreToCount(int saveCount);
1638dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1648dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
1658dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        SkCanvas::SaveFlags flags);
1668dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual int saveLayerAlpha(float left, float top, float right, float bottom,
1678dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            int alpha, SkCanvas::SaveFlags flags) {
1688dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        SkPaint paint;
1698dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        paint.setAlpha(alpha);
1708dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        return saveLayer(left, top, right, bottom, &paint, flags);
1718dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    }
1728dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1738dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // Matrix
1748dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); }
1758dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void setMatrix(const SkMatrix& matrix);
1768dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1778dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void concat(const SkMatrix& matrix);
1788dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void rotate(float degrees);
1798dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void scale(float sx, float sy);
1808dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void skew(float sx, float sy);
1818dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void translate(float dx, float dy);
1828dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1838dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // Clip
1848dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual bool getClipBounds(SkRect* outRect) const;
1858dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual bool quickRejectRect(float left, float top, float right, float bottom) const;
1868dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual bool quickRejectPath(const SkPath& path) const;
1878dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1888dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
1898dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual bool clipPath(const SkPath* path, SkRegion::Op op);
1908dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
1918dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1928dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // Misc
1938dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual SkDrawFilter* getDrawFilter() { return mDrawFilter.get(); }
1948dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void setDrawFilter(SkDrawFilter* filter);
1958dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
1968dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// ----------------------------------------------------------------------------
1978dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// android/graphics/Canvas draw operations
1988dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson// ----------------------------------------------------------------------------
1998dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawColor(int color, SkXfermode::Mode mode);
2008dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawPaint(const SkPaint& paint);
2018dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
2028dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // Geometry
2038dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawPoint(float x, float y, const SkPaint& paint) {
2048dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        float points[2] = { x, y };
2058dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        drawPoints(points, 2, paint);
2068dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    }
2078dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawPoints(const float* points, int count, const SkPaint& paint);
2088dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawLine(float startX, float startY, float stopX, float stopY,
2098dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            const SkPaint& paint) {
2108dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        float points[4] = { startX, startY, stopX, stopY };
2118dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        drawLines(points, 4, paint);
2128dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    }
2138dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawLines(const float* points, int count, const SkPaint& paint);
2148dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint);
2158dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawRoundRect(float left, float top, float right, float bottom,
2168dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            float rx, float ry, const SkPaint& paint);
2178dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawCircle(float x, float y, float radius, const SkPaint& paint);
2188dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint);
2198dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawArc(float left, float top, float right, float bottom,
2208dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint);
2218dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawPath(const SkPath& path, const SkPaint& paint);
2228dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
2238dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            const float* verts, const float* tex, const int* colors,
2248dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            const uint16_t* indices, int indexCount, const SkPaint& paint)
2258dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson        { LOG_ALWAYS_FATAL("DisplayListRenderer does not support drawVertices()"); }
2268dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
2278dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // Bitmap-based
2288dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint);
2298dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
2308dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson                            const SkPaint* paint);
2318dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
2328dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            float srcRight, float srcBottom, float dstLeft, float dstTop,
2338dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            float dstRight, float dstBottom, const SkPaint* paint);
2348dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
2358dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            const float* vertices, const int* colors, const SkPaint* paint);
2368dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
2378dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    // Text
2388dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawText(const uint16_t* glyphs, const float* positions, int count,
2398dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
2408dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            float boundsRight, float boundsBottom, float totalAdvance);
2418dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawPosText(const uint16_t* text, const float* positions, int count,
2428dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            int posCount, const SkPaint& paint);
2438dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
2448dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson            float hOffset, float vOffset, const SkPaint& paint);
2458dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson    virtual bool drawTextAbsolutePos() const { return false; }
2468dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
2478dfaa4904205772cdceee63ef3989bcdedf1a914Tom Hudson
2484aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyprivate:
249984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
250984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    CanvasState mState;
251984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
2528afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    enum DeferredBarrierType {
2538afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        kBarrier_None,
2548afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        kBarrier_InOrder,
2558afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        kBarrier_OutOfOrder,
2568afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    };
2578afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
2588afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    void flushRestoreToCount();
2598afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    void flushTranslate();
2608afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    void flushReorderBarrier();
2614aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    LinearAllocator& alloc() { return mDisplayListData->allocator; }
263b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik
264b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik    // Each method returns final index of op
2658afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    size_t addOpAndUpdateChunk(DisplayListOp* op);
2668afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    // flushes any deferred operations, and appends the op
2678afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    size_t flushAndAddOp(DisplayListOp* op);
2688afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
2698afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    size_t addStateOp(StateOp* op);
2708afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    size_t addDrawOp(DrawOp* op);
2718afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    size_t addRenderNodeOp(DrawRenderNodeOp* op);
2728afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
2734aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2742af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    template<class T>
275d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    inline const T* refBuffer(const T* srcBuffer, int32_t count) {
276e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik        if (!srcBuffer) return nullptr;
277d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik
2782af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
2792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        memcpy(dstBuffer, srcBuffer, count * sizeof(T));
2802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        return dstBuffer;
2814aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    }
2824aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
2832af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    inline char* refText(const char* text, size_t byteLength) {
2842af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
2854aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    }
2864aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
287d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    inline const SkPath* refPath(const SkPath* path) {
288e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik        if (!path) return nullptr;
2892fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy
29051d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        const SkPath* cachedPath = mPathMap.valueFor(path);
29151d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        if (cachedPath == nullptr || cachedPath->getGenerationID() != path->getGenerationID()) {
292d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik            SkPath* newPathCopy = new SkPath(*path);
293d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik            newPathCopy->setSourcePath(path);
29451d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            cachedPath = newPathCopy;
29551d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            std::unique_ptr<const SkPath> copy(newPathCopy);
29651d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            mDisplayListData->paths.push_back(std::move(copy));
297d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik
29896ebc6b5097ab73eef45e094241e444f4c21bfccRomain Guy            // replaceValueFor() performs an add if the entry doesn't exist
29951d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            mPathMap.replaceValueFor(path, cachedPath);
3004aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        }
30144fd8d24f761f82d21e9b00932648a1b6bf91449John Reck        if (mDisplayListData->sourcePaths.indexOf(path) < 0) {
302a35778c799e8073a42b9e22191bde9d838327ab7John Reck            mResourceCache.incrementRefcount(path);
30344fd8d24f761f82d21e9b00932648a1b6bf91449John Reck            mDisplayListData->sourcePaths.add(path);
304d34dd71800d9a1077e58c3b7f2511c46848da417Chet Haase        }
30551d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        return cachedPath;
3064aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy    }
3074aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
308d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    inline const SkPaint* refPaint(const SkPaint* paint) {
309e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik        if (!paint) return nullptr;
3100fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy
31109c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        // If there is a draw filter apply it here and store the modified paint
31209c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        // so that we don't need to modify the paint every time we access it.
313da3198a550bdd91ccdc8a09c3a6e00d3b61c0c20Chris Craik        SkTLazy<SkPaint> filteredPaint;
31409c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        if (mDrawFilter.get()) {
31551d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            paint = filteredPaint.init();
31651d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type);
31709c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        }
31809c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger
31909c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        // compute the hash key for the paint and check the cache.
32009c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        const uint32_t key = paint->getHash();
32109c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        const SkPaint* cachedPaint = mPaintMap.valueFor(key);
32209c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        // In the unlikely event that 2 unique paints have the same hash we do a
32309c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        // object equality check to ensure we don't erroneously dedup them.
324e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik        if (cachedPaint == nullptr || *cachedPaint != *paint) {
32551d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            cachedPaint = new SkPaint(*paint);
32651d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            std::unique_ptr<const SkPaint> copy(cachedPaint);
32751d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            mDisplayListData->paints.push_back(std::move(copy));
32851d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik
32996ebc6b5097ab73eef45e094241e444f4c21bfccRomain Guy            // replaceValueFor() performs an add if the entry doesn't exist
33009c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger            mPaintMap.replaceValueFor(key, cachedPaint);
331d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase        }
3320fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy
33309c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger        return cachedPaint;
3340fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy    }
3350fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy
336cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    inline SkPaint* copyPaint(const SkPaint* paint) {
337e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik        if (!paint) return nullptr;
338cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
33951d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        SkPaint* returnPaint = new SkPaint(*paint);
34051d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        std::unique_ptr<const SkPaint> copy(returnPaint);
34151d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        mDisplayListData->paints.push_back(std::move(copy));
34251d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik
34351d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        return returnPaint;
344cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    }
345cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
346d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    inline const SkRegion* refRegion(const SkRegion* region) {
347735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy        if (!region) {
348735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy            return region;
349735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy        }
350735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
35151d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        const SkRegion* cachedRegion = mRegionMap.valueFor(region);
352735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy        // TODO: Add generation ID to SkRegion
35351d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        if (cachedRegion == nullptr) {
35451d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            std::unique_ptr<const SkRegion> copy(new SkRegion(*region));
35551d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            cachedRegion = copy.get();
35651d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            mDisplayListData->regions.push_back(std::move(copy));
35751d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik
358735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy            // replaceValueFor() performs an add if the entry doesn't exist
35951d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik            mRegionMap.replaceValueFor(region, cachedRegion);
360735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy        }
361735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
36251d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik        return cachedRegion;
363735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy    }
364735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
365d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    inline const SkBitmap* refBitmap(const SkBitmap* bitmap) {
366d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase        // Note that this assumes the bitmap is immutable. There are cases this won't handle
367d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
368d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase        // contents, and drawing again. The only fix would be to always copy it the first time,
369d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase        // which doesn't seem worth the extra cycles for this unlikely case.
37044fd8d24f761f82d21e9b00932648a1b6bf91449John Reck        mDisplayListData->bitmapResources.add(bitmap);
371a35778c799e8073a42b9e22191bde9d838327ab7John Reck        mResourceCache.incrementRefcount(bitmap);
3722af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        return bitmap;
3735c13d89c1332fcc499379b9064b891187b75ca32Chet Haase    }
3744aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
375d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) {
37644fd8d24f761f82d21e9b00932648a1b6bf91449John Reck        mDisplayListData->ownedBitmapResources.add(bitmap);
377a35778c799e8073a42b9e22191bde9d838327ab7John Reck        mResourceCache.incrementRefcount(bitmap);
3782af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        return bitmap;
37949c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    }
38049c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy
381d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
38244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck        mDisplayListData->patchResources.add(patch);
383a35778c799e8073a42b9e22191bde9d838327ab7John Reck        mResourceCache.incrementRefcount(patch);
384e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy        return patch;
385e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    }
386e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy
38709c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger    DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap;
388d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
389d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
39024c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy
391a35778c799e8073a42b9e22191bde9d838327ab7John Reck    ResourceCache& mResourceCache;
39244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    DisplayListData* mDisplayListData;
39358ecc204fbcacef34806290492384677a330d4d4Romain Guy
39433f6beb10f98e8ba96250e284876d607055d278dRomain Guy    float mTranslateX;
39533f6beb10f98e8ba96250e284876d607055d278dRomain Guy    float mTranslateY;
3968afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    bool mHasDeferredTranslate;
3978afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    DeferredBarrierType mDeferredBarrierType;
398cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    bool mHighContrastText;
39954c1a64d5441a964890b44280e4457e11f4f924aRomain Guy
400eea6ef9c767c734797912022113191dd255c4ae6Chris Craik    int mRestoreSaveCount;
401eea6ef9c767c734797912022113191dd255c4ae6Chris Craik
40209c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger    SkAutoTUnref<SkDrawFilter> mDrawFilter;
40309c2d4fe15fbac2faf8a97ba2cc59132ee12222aDerek Sollenberger
404e18264b079481a244b30e3f71012c53bbd861f92John Reck    friend class RenderNode;
405b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
4064aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // class DisplayListRenderer
4074aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
4084aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace uirenderer
4094aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace android
4104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
4115b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
412