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
174aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#define LOG_TAG "OpenGLRenderer"
184aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
19d5a85fb63d91a9297e8d9a11016f3b3ed60dfbabRomain Guy#include <SkCamera.h>
20c46d07a29e94807e768f8b162ce9f77a88ba6f46Romain Guy#include <SkCanvas.h>
219c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
226554943a1dd6854c0f4976900956e556767b49e1Romain Guy#include <private/hwui/DrawGlInfo.h>
236554943a1dd6854c0f4976900956e556767b49e1Romain Guy
24a35778c799e8073a42b9e22191bde9d838327ab7John Reck#include "ResourceCache.h"
25c3566d06421c8acc0aafb18f7e307e5725ce87e1Chris Craik#include "DeferredDisplayList.h"
2612f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck#include "DeferredLayerUpdater.h"
279c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase#include "DisplayListLogBuffer.h"
282af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik#include "DisplayListOp.h"
294aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy#include "DisplayListRenderer.h"
30113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "RenderNode.h"
3113631f3da855f200a151e7837ed9f6b079622b58Romain Guy
324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guynamespace android {
334aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guynamespace uirenderer {
344aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
35cce47eb580d666ead1f6095d1e3b65233592bbaaChris CraikDisplayListRenderer::DisplayListRenderer()
36a35778c799e8073a42b9e22191bde9d838327ab7John Reck    : mResourceCache(ResourceCache::getInstance())
378afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    , mDisplayListData(NULL)
38cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    , mTranslateX(0.0f)
39cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    , mTranslateY(0.0f)
408afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    , mDeferredBarrierType(kBarrier_None)
41cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    , mHighContrastText(false)
42cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    , mRestoreSaveCount(-1) {
434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
444aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
454aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain GuyDisplayListRenderer::~DisplayListRenderer() {
4644fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    LOG_ALWAYS_FATAL_IF(mDisplayListData,
4744fd8d24f761f82d21e9b00932648a1b6bf91449John Reck            "Destroyed a DisplayListRenderer during a record!");
484aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
494aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
5044fd8d24f761f82d21e9b00932648a1b6bf91449John Reck///////////////////////////////////////////////////////////////////////////////
5144fd8d24f761f82d21e9b00932648a1b6bf91449John Reck// Operations
5244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck///////////////////////////////////////////////////////////////////////////////
53d34dd71800d9a1077e58c3b7f2511c46848da417Chet Haase
5444fd8d24f761f82d21e9b00932648a1b6bf91449John ReckDisplayListData* DisplayListRenderer::finishRecording() {
5543ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy    mPaintMap.clear();
56735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy    mRegionMap.clear();
572fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy    mPathMap.clear();
5844fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    DisplayListData* data = mDisplayListData;
5944fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    mDisplayListData = 0;
6044fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    return data;
615977baa1fa24125c148a72699b53e62abaf08960Chet Haase}
625977baa1fa24125c148a72699b53e62abaf08960Chet Haase
637c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guystatus_t DisplayListRenderer::prepareDirty(float left, float top,
647d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        float right, float bottom, bool opaque) {
6544fd8d24f761f82d21e9b00932648a1b6bf91449John Reck
6644fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    LOG_ALWAYS_FATAL_IF(mDisplayListData,
6744fd8d24f761f82d21e9b00932648a1b6bf91449John Reck            "prepareDirty called a second time during a recording!");
6844fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    mDisplayListData = new DisplayListData();
6944fd8d24f761f82d21e9b00932648a1b6bf91449John Reck
7069e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik    initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3());
7145e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy
728afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    mDeferredBarrierType = kBarrier_InOrder;
7345e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy    mDirtyClip = opaque;
7427454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    mRestoreSaveCount = -1;
7545e4c3df6c00ac98ff6144de9af574877d4fff19Romain Guy
7644b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
7727454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy}
7827454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy
7927454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guyvoid DisplayListRenderer::finish() {
808afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushRestoreToCount();
818afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
82b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy}
83b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
84daf98e941e140e8739458126640183b9f296a2abChet Haasevoid DisplayListRenderer::interrupt() {
85daf98e941e140e8739458126640183b9f296a2abChet Haase}
86daf98e941e140e8739458126640183b9f296a2abChet Haase
872b1847ea60650a9f68372abe860415f18b55081dRomain Guyvoid DisplayListRenderer::resume() {
884aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
894aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
906554943a1dd6854c0f4976900956e556767b49e1Romain Guystatus_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
91cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    // Ignore dirty during recording, it matters only when we replay
922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawFunctorOp(functor));
9309d5cddf67b676018700bcc10a72242641cd7eecJohn Reck    mDisplayListData->functors.add(functor);
946554943a1dd6854c0f4976900956e556767b49e1Romain Guy    return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
95daf98e941e140e8739458126640183b9f296a2abChet Haase}
96daf98e941e140e8739458126640183b9f296a2abChet Haase
974aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyint DisplayListRenderer::save(int flags) {
982af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) SaveOp(flags));
9914e513058ed4168c94e015638d16f5f87fd8063aChris Craik    return StatefulBaseRenderer::save(flags);
1004aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1014aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1024aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyvoid DisplayListRenderer::restore() {
10304c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy    if (mRestoreSaveCount < 0) {
10433f6beb10f98e8ba96250e284876d607055d278dRomain Guy        restoreToCount(getSaveCount() - 1);
10533f6beb10f98e8ba96250e284876d607055d278dRomain Guy        return;
10604c9d8c2ffd028c35c750bac0a4a7b79e48059b5Romain Guy    }
10733f6beb10f98e8ba96250e284876d607055d278dRomain Guy
10833f6beb10f98e8ba96250e284876d607055d278dRomain Guy    mRestoreSaveCount--;
1098afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
11014e513058ed4168c94e015638d16f5f87fd8063aChris Craik    StatefulBaseRenderer::restore();
1114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1134aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyvoid DisplayListRenderer::restoreToCount(int saveCount) {
11427454a42de8b3c54cdd3b2b2a12446c2c10c8cb9Romain Guy    mRestoreSaveCount = saveCount;
1158afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
11614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    StatefulBaseRenderer::restoreToCount(saveCount);
1174aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1184aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyint DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
120d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger        const SkPaint* paint, int flags) {
1214ace7305608442ab35ea9aa65a4220df152c187fChris Craik    // force matrix/clip isolation for layer
1224ace7305608442ab35ea9aa65a4220df152c187fChris Craik    flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag;
1234ace7305608442ab35ea9aa65a4220df152c187fChris Craik
124d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger    paint = refPaint(paint);
125d44fbe55a9f434cb5bb0e34c143ba1445141990dDerek Sollenberger    addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags));
12614e513058ed4168c94e015638d16f5f87fd8063aChris Craik    return StatefulBaseRenderer::save(flags);
1275b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy}
1285b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy
129b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craikvoid DisplayListRenderer::translate(float dx, float dy, float dz) {
130b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik    // ignore dz, not used at defer time
1318afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    mHasDeferredTranslate = true;
13233f6beb10f98e8ba96250e284876d607055d278dRomain Guy    mTranslateX += dx;
13333f6beb10f98e8ba96250e284876d607055d278dRomain Guy    mTranslateY += dy;
1348afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushRestoreToCount();
13514e513058ed4168c94e015638d16f5f87fd8063aChris Craik    StatefulBaseRenderer::translate(dx, dy, dz);
1364aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1384aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyvoid DisplayListRenderer::rotate(float degrees) {
1392af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) RotateOp(degrees));
14014e513058ed4168c94e015638d16f5f87fd8063aChris Craik    StatefulBaseRenderer::rotate(degrees);
1414aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1424aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyvoid DisplayListRenderer::scale(float sx, float sy) {
1442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ScaleOp(sx, sy));
14514e513058ed4168c94e015638d16f5f87fd8063aChris Craik    StatefulBaseRenderer::scale(sx, sy);
1464aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1474aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
148807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guyvoid DisplayListRenderer::skew(float sx, float sy) {
1492af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) SkewOp(sx, sy));
15014e513058ed4168c94e015638d16f5f87fd8063aChris Craik    StatefulBaseRenderer::skew(sx, sy);
151807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy}
152807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy
153139088228faa7f3c446af7387e017933998a5570Derek Sollenbergervoid DisplayListRenderer::setMatrix(const SkMatrix& matrix) {
1542af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) SetMatrixOp(matrix));
15514e513058ed4168c94e015638d16f5f87fd8063aChris Craik    StatefulBaseRenderer::setMatrix(matrix);
1564aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1574aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
158139088228faa7f3c446af7387e017933998a5570Derek Sollenbergervoid DisplayListRenderer::concatMatrix(const SkMatrix& matrix) {
1592af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ConcatMatrixOp(matrix));
16014e513058ed4168c94e015638d16f5f87fd8063aChris Craik    StatefulBaseRenderer::concatMatrix(matrix);
1614aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1624aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
1634aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guybool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
1644aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        SkRegion::Op op) {
1652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
166d6b65f67717025b1162f86f04e2caa5723566cacChris Craik    return StatefulBaseRenderer::clipRect(left, top, right, bottom, op);
1674aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
1684aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
169d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikbool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
1702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    path = refPath(path);
1712af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ClipPathOp(path, op));
172d6b65f67717025b1162f86f04e2caa5723566cacChris Craik    return StatefulBaseRenderer::clipPath(path, op);
173735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy}
174735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
175d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikbool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
1762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    region = refRegion(region);
1772af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ClipRegionOp(region, op));
178d6b65f67717025b1162f86f04e2caa5723566cacChris Craik    return StatefulBaseRenderer::clipRegion(region, op);
179735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy}
180735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
181a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craikstatus_t DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) {
1828afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");
1838afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
184cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    // dirty is an out parameter and should not be recorded,
185cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    // it matters only when replaying the display list
186b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik    DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *currentTransform());
1878afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    addRenderNodeOp(op);
1882af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
1896554943a1dd6854c0f4976900956e556767b49e1Romain Guy    return DrawGlInfo::kStatusDone;
1900fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy}
1910fe478ea04720a57ef3919dbc23711bc7eba517fRomain Guy
19212f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reckstatus_t DisplayListRenderer::drawLayer(DeferredLayerUpdater* layerHandle, float x, float y) {
19312f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck    // We ref the DeferredLayerUpdater due to its thread-safe ref-counting
19412f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck    // semantics.
19512f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck    mDisplayListData->ref(layerHandle);
19612f5e3433226f0a2886a98b0b8da8d5e947c5cdeJohn Reck    addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer(), x, y));
197486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
1986c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}
1996c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
200796475006f5d670e8383a2050f11719522437a43Chris Craikstatus_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
2012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    bitmap = refBitmap(bitmap);
2022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
2032af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
204796475006f5d670e8383a2050f11719522437a43Chris Craik    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint));
205486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
2064aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
2074aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
208d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikstatus_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
2094aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy        float srcRight, float srcBottom, float dstLeft, float dstTop,
210d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        float dstRight, float dstBottom, const SkPaint* paint) {
211796475006f5d670e8383a2050f11719522437a43Chris Craik    if (srcLeft == 0 && srcTop == 0
212796475006f5d670e8383a2050f11719522437a43Chris Craik            && srcRight == bitmap->width() && srcBottom == bitmap->height()
213796475006f5d670e8383a2050f11719522437a43Chris Craik            && (srcBottom - srcTop == dstBottom - dstTop)
214796475006f5d670e8383a2050f11719522437a43Chris Craik            && (srcRight - srcLeft == dstRight - dstLeft)) {
215527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik        // transform simple rect to rect drawing case into position bitmap ops, since they merge
216796475006f5d670e8383a2050f11719522437a43Chris Craik        save(SkCanvas::kMatrix_SaveFlag);
217796475006f5d670e8383a2050f11719522437a43Chris Craik        translate(dstLeft, dstTop);
218796475006f5d670e8383a2050f11719522437a43Chris Craik        drawBitmap(bitmap, paint);
219796475006f5d670e8383a2050f11719522437a43Chris Craik        restore();
220796475006f5d670e8383a2050f11719522437a43Chris Craik    } else {
221796475006f5d670e8383a2050f11719522437a43Chris Craik        bitmap = refBitmap(bitmap);
222796475006f5d670e8383a2050f11719522437a43Chris Craik        paint = refPaint(paint);
223796475006f5d670e8383a2050f11719522437a43Chris Craik
224796475006f5d670e8383a2050f11719522437a43Chris Craik        addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
225796475006f5d670e8383a2050f11719522437a43Chris Craik                srcLeft, srcTop, srcRight, srcBottom,
226796475006f5d670e8383a2050f11719522437a43Chris Craik                dstLeft, dstTop, dstRight, dstBottom, paint));
227527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik    }
228486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
2294aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
2304aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
231796475006f5d670e8383a2050f11719522437a43Chris Craikstatus_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
2322af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    bitmap = refBitmapData(bitmap);
2332af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
2342af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
235796475006f5d670e8383a2050f11719522437a43Chris Craik    addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint));
236486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
237e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy}
238e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy
239d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikstatus_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
240d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        const float* vertices, const int* colors, const SkPaint* paint) {
2410664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik    int vertexCount = (meshWidth + 1) * (meshHeight + 1);
2422af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    bitmap = refBitmap(bitmap);
2430664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik    vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex
2442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
2450664fef9e2a36025b3fad85b57b4d10617b4d66eChris Craik    colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex
2462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
2472af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight,
2482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    vertices, colors, paint));
249486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
2505a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy}
2515a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
252d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikstatus_t DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
253d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        float left, float top, float right, float bottom, const SkPaint* paint) {
2542af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    bitmap = refBitmap(bitmap);
255e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy    patch = refPatch(patch);
25616ea8d373b03b1e115dd505af70dbee4e3a3a182Romain Guy    paint = refPaint(paint);
2572af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
25803c00b5a135e68d22ca5bb829b899ebda6ed7e9dRomain Guy    addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint));
259486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
2604aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
2614aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
262486590963e2207d68eebd6944fec70d50d41116aChet Haasestatus_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
2632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawColorOp(color, mode));
264486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
2654aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
2664aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
267486590963e2207d68eebd6944fec70d50d41116aChet Haasestatus_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
268d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        const SkPaint* paint) {
2692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
2702af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
271486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
2724aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
2734aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
274486590963e2207d68eebd6944fec70d50d41116aChet Haasestatus_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
275d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        float rx, float ry, const SkPaint* paint) {
2762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
2772af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
278486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
27901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
28001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
281072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggistatus_t DisplayListRenderer::drawRoundRect(
282072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
283072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
284072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
285072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        CanvasPropertyPaint* paint) {
2860e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(left);
2870e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(top);
2880e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(right);
2890e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(bottom);
2900e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(rx);
2910e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(ry);
2920e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(paint);
293072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
294072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi            &right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
295072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    return DrawGlInfo::kStatusDone;
296072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi}
297072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi
298d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikstatus_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) {
2992af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3002af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
301486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
30201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
30301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
30452244fff29042926e21fa897ef5ab11148e35299John Reckstatus_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
30552244fff29042926e21fa897ef5ab11148e35299John Reck        CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
3060e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(x);
3070e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(y);
3080e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(radius);
3090e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck    mDisplayListData->ref(paint);
31052244fff29042926e21fa897ef5ab11148e35299John Reck    addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value,
31152244fff29042926e21fa897ef5ab11148e35299John Reck            &radius->value, &paint->value));
31252244fff29042926e21fa897ef5ab11148e35299John Reck    return DrawGlInfo::kStatusDone;
31352244fff29042926e21fa897ef5ab11148e35299John Reck}
31452244fff29042926e21fa897ef5ab11148e35299John Reck
315486590963e2207d68eebd6944fec70d50d41116aChet Haasestatus_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
316d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        const SkPaint* paint) {
3172af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3182af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
319486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
320c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}
321c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
322486590963e2207d68eebd6944fec70d50d41116aChet Haasestatus_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
323d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
324544e524db6e4da526af1c897fe5314036ede5012Chris Craik    if (fabs(sweepAngle) >= 360.0f) {
3256ac174b97246ed40fe780b29561603b61770fa17Chris Craik        return drawOval(left, top, right, bottom, paint);
3266ac174b97246ed40fe780b29561603b61770fa17Chris Craik    }
3276ac174b97246ed40fe780b29561603b61770fa17Chris Craik
3282af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3292af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
3302af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                    startAngle, sweepAngle, useCenter, paint));
331486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
3328b2f5267f16c295f12faab810527cd6311997e34Romain Guy}
3338b2f5267f16c295f12faab810527cd6311997e34Romain Guy
334d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikstatus_t DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
3352af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    path = refPath(path);
3362af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3382af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawPathOp(path, paint));
339486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
3404aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
3414aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
342d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikstatus_t DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
3432af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    points = refBuffer<float>(points, count);
3442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3452af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3462af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawLinesOp(points, count, paint));
347486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
348ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy}
349ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy
350d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikstatus_t DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
3512af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    points = refBuffer<float>(points, count);
3522af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3532af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3542af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawPointsOp(points, count, paint));
355486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
3564aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}
3574aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy
358996e57c84368058be793897ebc355b917a59abc2Raph Levienstatus_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
359d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
360996e57c84368058be793897ebc355b917a59abc2Raph Levien    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
3612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    text = refText(text, bytesCount);
3632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    path = refPath(path);
3642af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3652af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path,
3672af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            hOffset, vOffset, paint);
3680f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    addDrawOp(op);
369996e57c84368058be793897ebc355b917a59abc2Raph Levien    return DrawGlInfo::kStatusDone;
370996e57c84368058be793897ebc355b917a59abc2Raph Levien}
371996e57c84368058be793897ebc355b917a59abc2Raph Levien
372996e57c84368058be793897ebc355b917a59abc2Raph Levienstatus_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
373d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        const float* positions, const SkPaint* paint) {
374996e57c84368058be793897ebc355b917a59abc2Raph Levien    if (!text || count <= 0) return DrawGlInfo::kStatusDone;
3752af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3762af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    text = refText(text, bytesCount);
3772af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    positions = refBuffer<float>(positions, count * 2);
3782af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
3792af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
3802af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint);
3810f6675332c04c74909425d1d328f02b32c0ff40eRomain Guy    addDrawOp(op);
382996e57c84368058be793897ebc355b917a59abc2Raph Levien    return DrawGlInfo::kStatusDone;
383996e57c84368058be793897ebc355b917a59abc2Raph Levien}
384996e57c84368058be793897ebc355b917a59abc2Raph Levien
385cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craikstatic void simplifyPaint(int color, SkPaint* paint) {
386cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    paint->setColor(color);
387cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    paint->setShader(NULL);
388cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    paint->setColorFilter(NULL);
389cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    paint->setLooper(NULL);
390cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    paint->setStrokeWidth(4 + 0.04 * paint->getTextSize());
391cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    paint->setStrokeJoin(SkPaint::kRound_Join);
392cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    paint->setLooper(NULL);
393cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik}
394cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
395c25259519f1b74bb62a2b051b74537f073436b5cRomain Guystatus_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
396d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik        float x, float y, const float* positions, const SkPaint* paint,
39741541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik        float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
398527a3aace1dd72432c2e0472a570e030ad04bf16Chris Craik
399947eabf42d835d0dfb0daa2fe6d869139c7000d6Chris Craik    if (!text || count <= 0 || paintWillNotDrawText(*paint)) return DrawGlInfo::kStatusDone;
40033f6beb10f98e8ba96250e284876d607055d278dRomain Guy
4012af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    text = refText(text, bytesCount);
4022af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    positions = refBuffer<float>(positions, count * 2);
40333f6beb10f98e8ba96250e284876d607055d278dRomain Guy
404cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    if (CC_UNLIKELY(mHighContrastText)) {
405cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        // high contrast draw path
406cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        int color = paint->getColor();
407cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color);
408cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        bool darken = channelSum < (128 * 3);
409cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
410cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        // outline
411cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        SkPaint* outlinePaint = copyPaint(paint);
412cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, outlinePaint);
413cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        outlinePaint->setStyle(SkPaint::kStrokeAndFill_Style);
414cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count,
415cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                x, y, positions, outlinePaint, totalAdvance, bounds)); // bounds?
416cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
417cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        // inner
418cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        SkPaint* innerPaint = copyPaint(paint);
419cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, innerPaint);
420cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        innerPaint->setStyle(SkPaint::kFill_Style);
421cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count,
422cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                x, y, positions, innerPaint, totalAdvance, bounds));
423cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    } else {
424cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        // standard draw path
425cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        paint = refPaint(paint);
426cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
427cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count,
428cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                x, y, positions, paint, totalAdvance, bounds);
429cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        addDrawOp(op);
430cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    }
431486590963e2207d68eebd6944fec70d50d41116aChet Haase    return DrawGlInfo::kStatusDone;
432672433d90fab7383cd28beac9d4485b566a90940Romain Guy}
433672433d90fab7383cd28beac9d4485b566a90940Romain Guy
434d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craikstatus_t DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
435672433d90fab7383cd28beac9d4485b566a90940Romain Guy    if (count <= 0) return DrawGlInfo::kStatusDone;
436672433d90fab7383cd28beac9d4485b566a90940Romain Guy
4372af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    rects = refBuffer<float>(rects, count);
4382af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    paint = refPaint(paint);
4392af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
440672433d90fab7383cd28beac9d4485b566a90940Romain Guy    return DrawGlInfo::kStatusDone;
441eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy}
442eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
4435ff9df658230d49e42c43586997a02d8e4dd417eRomain Guyvoid DisplayListRenderer::resetPaintFilter() {
4442af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) ResetPaintFilterOp());
4455ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy}
4465ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy
4475ff9df658230d49e42c43586997a02d8e4dd417eRomain Guyvoid DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
4482af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits));
4492af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
4502af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4518afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craikvoid DisplayListRenderer::insertReorderBarrier(bool enableReorder) {
4528afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushRestoreToCount();
4538afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
4548afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    mDeferredBarrierType = enableReorder ? kBarrier_OutOfOrder : kBarrier_InOrder;
4558afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
4568afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
4578afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craikvoid DisplayListRenderer::flushRestoreToCount() {
4582af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    if (mRestoreSaveCount >= 0) {
4598afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        addOpAndUpdateChunk(new (alloc()) RestoreToCountOp(mRestoreSaveCount));
4602af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        mRestoreSaveCount = -1;
4612af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
4622af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
4632af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4648afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craikvoid DisplayListRenderer::flushTranslate() {
4658afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    if (mHasDeferredTranslate) {
4662af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
4678afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik            addOpAndUpdateChunk(new (alloc()) TranslateOp(mTranslateX, mTranslateY));
4682af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            mTranslateX = mTranslateY = 0.0f;
4692af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        }
4708afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        mHasDeferredTranslate = false;
4712af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
4722af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
4732af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4748afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craiksize_t DisplayListRenderer::addOpAndUpdateChunk(DisplayListOp* op) {
4758afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    int insertIndex = mDisplayListData->displayListOps.add(op);
4768afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    if (mDeferredBarrierType != kBarrier_None) {
4778afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        // op is first in new chunk
4788afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        mDisplayListData->chunks.push();
4798afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        DisplayListData::Chunk& newChunk = mDisplayListData->chunks.editTop();
4808afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        newChunk.beginOpIndex = insertIndex;
4818afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        newChunk.endOpIndex = insertIndex + 1;
4828afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder);
4838afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
4848afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        int nextChildIndex = mDisplayListData->children().size();
4858afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex;
4868afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        mDeferredBarrierType = kBarrier_None;
4878afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    } else {
4888afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        // standard case - append to existing chunk
4898afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        mDisplayListData->chunks.editTop().endOpIndex = insertIndex + 1;
4908afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
4918afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return insertIndex;
4922af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik}
4932af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik
4948afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craiksize_t DisplayListRenderer::flushAndAddOp(DisplayListOp* op) {
4958afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushRestoreToCount();
4968afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    flushTranslate();
4978afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return addOpAndUpdateChunk(op);
4988afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
4998afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
5008afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craiksize_t DisplayListRenderer::addStateOp(StateOp* op) {
5018afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return flushAndAddOp(op);
5028afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
5038afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
5048afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craiksize_t DisplayListRenderer::addDrawOp(DrawOp* op) {
5052af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    Rect localBounds;
5063b20251a355c88193c439f928a84ae69483fb488John Reck    if (op->getLocalBounds(localBounds)) {
507f0a590781b2c3e34132b2011d3956135add73ae0Chris Craik        bool rejected = quickRejectConservative(localBounds.left, localBounds.top,
5082af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik                localBounds.right, localBounds.bottom);
5092af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik        op->setQuickRejected(rejected);
5102af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik    }
511c1c5f0870282b56dafe5a4d756e4b9e6884655a7Chris Craik
51244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    mDisplayListData->hasDrawOps = true;
5138afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return flushAndAddOp(op);
5148afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
5158afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
5168afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craiksize_t DisplayListRenderer::addRenderNodeOp(DrawRenderNodeOp* op) {
5178afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    int opIndex = addDrawOp(op);
5188afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    int childIndex = mDisplayListData->addChild(op);
5198afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
5208afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    // update the chunk's child indices
5218afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    DisplayListData::Chunk& chunk = mDisplayListData->chunks.editTop();
5228afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    chunk.endChildIndex = childIndex + 1;
5238afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
5248afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    if (op->renderNode()->stagingProperties().isProjectionReceiver()) {
5258afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        // use staging property, since recording on UI thread
5268afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        mDisplayListData->projectionReceiveIndex = opIndex;
5278afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    }
5288afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    return opIndex;
5295ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy}
5305ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy
5314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace uirenderer
5324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy}; // namespace android
533