1e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/*
2e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Copyright (C) 2010 The Android Open Source Project
3e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
4e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * you may not use this file except in compliance with the License.
6e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * You may obtain a copy of the License at
7e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
8e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
10e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Unless required by applicable law or agreed to in writing, software
11e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * See the License for the specific language governing permissions and
14e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * limitations under the License.
15e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
16e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
17a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy#define LOG_TAG "OpenGLRenderer"
18a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy
19e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include "jni.h"
20e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy#include "GraphicsJNI.h"
21e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <nativehelper/JNIHelp.h>
226554943a1dd6854c0f4976900956e556767b49e1Romain Guy
23e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <android_runtime/AndroidRuntime.h>
246554943a1dd6854c0f4976900956e556767b49e1Romain Guy
25b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/ResourceTypes.h>
26e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
276554943a1dd6854c0f4976900956e556767b49e1Romain Guy#include <private/hwui/DrawGlInfo.h>
286554943a1dd6854c0f4976900956e556767b49e1Romain Guy
296554943a1dd6854c0f4976900956e556767b49e1Romain Guy#include <cutils/properties.h>
308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
31ce0537b80087a6225273040a987414b1dd081aa0Romain Guy#include <SkBitmap.h>
32c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy#include <SkCanvas.h>
3357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III#include <SkImageInfo.h>
34f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy#include <SkMatrix.h>
352ce932832e7caa1a6021539a9b7828ee5f49a610Chris Craik#include <SkPorterDuff.h>
36079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy#include <SkRegion.h>
37a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy#include <SkScalerContext.h>
3861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy#include <SkTemplates.h>
3985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <SkXfermode.h>
40e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
41b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy#include <DisplayListRenderer.h>
429d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <Rect.h>
43113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include <RenderNode.h>
4452244fff29042926e21fa897ef5ab11148e35299John Reck#include <CanvasProperty.h>
456ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod#include <Paint.h>
460e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck#include <renderthread/RenderProxy.h>
4785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
481a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "MinikinUtils.h"
49e8e62a4a032a80409114a37908b5f18ab0080848Romain Guy
50e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guynamespace android {
51e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
529d5316e3f56d138504565ff311145ac01621dff4Romain Guyusing namespace uirenderer;
539d5316e3f56d138504565ff311145ac01621dff4Romain Guy
54163935113919a184122b8b3bd672ef08c8df65dcRomain Guy/**
553b20251a355c88193c439f928a84ae69483fb488John Reck * Note: DisplayListRenderer JNI layer is generated and compiled only on supported
56163935113919a184122b8b3bd672ef08c8df65dcRomain Guy *       devices. This means all the logic must be compiled only when the
57163935113919a184122b8b3bd672ef08c8df65dcRomain Guy *       preprocessor variable USE_OPENGL_RENDERER is defined.
58163935113919a184122b8b3bd672ef08c8df65dcRomain Guy */
59163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER
60163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
61244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ----------------------------------------------------------------------------
62bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy// Defines
63244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ----------------------------------------------------------------------------
64bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy
65bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy// Debug
66e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy#define DEBUG_RENDERER 0
67bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy
68bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy// Debug
69bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy#if DEBUG_RENDERER
705baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__)
71bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy#else
72bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy    #define RENDERER_LOGD(...)
73bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy#endif
74e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy
759d5316e3f56d138504565ff311145ac01621dff4Romain Guy// ----------------------------------------------------------------------------
769d5316e3f56d138504565ff311145ac01621dff4Romain Guy
779d5316e3f56d138504565ff311145ac01621dff4Romain Guystatic struct {
787ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    jmethodID set;
799d5316e3f56d138504565ff311145ac01621dff4Romain Guy} gRectClassInfo;
809d5316e3f56d138504565ff311145ac01621dff4Romain Guy
81e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
82e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// Constructors
83e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
84e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
855c13d89c1332fcc499379b9064b891187b75ca32Chet Haasestatic void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz,
8636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
873b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
883b20251a355c88193c439f928a84ae69483fb488John Reck    RENDERER_LOGD("Destroy DisplayListRenderer");
89f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    delete renderer;
90e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
91e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
92e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
93e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// Setup
94e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
95e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
967d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz,
9736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint width, jint height) {
983b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
99f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    renderer->setViewport(width, height);
100e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
101e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
102cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craikstatic void android_view_GLES20Canvas_setHighContrastText(JNIEnv* env, jobject clazz,
103cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        jlong rendererPtr, jboolean highContrastText) {
104cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
105cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    renderer->setHighContrastText(highContrastText);
106cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik}
107cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
1088afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craikstatic void android_view_GLES20Canvas_insertReorderBarrier(JNIEnv* env, jobject clazz,
1098afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik        jlong rendererPtr, jboolean reorderEnable) {
1108afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
1118afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik    renderer->insertReorderBarrier(reorderEnable);
1128afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik}
1138afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik
11444b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haasestatic int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
11536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jboolean opaque) {
1163b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
11744b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase    return renderer->prepare(opaque);
118e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
119e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
12044b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haasestatic int android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
12136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint left, jint top, jint right, jint bottom,
1227d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        jboolean opaque) {
1233b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
12444b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase    return renderer->prepareDirty(left, top, right, bottom, opaque);
1257d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy}
1267d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy
1277d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
12836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
1293b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
130b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    renderer->finish();
131b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy}
132b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
133ba9b613437c34873fa95800a25fc51720638267cChris Craikstatic void android_view_GLES20Canvas_setProperty(JNIEnv* env,
134ba9b613437c34873fa95800a25fc51720638267cChris Craik        jobject clazz, jstring name, jstring value) {
135ba9b613437c34873fa95800a25fc51720638267cChris Craik    if (!Caches::hasInstance()) {
136ba9b613437c34873fa95800a25fc51720638267cChris Craik        ALOGW("can't set property, no Caches instance");
137ba9b613437c34873fa95800a25fc51720638267cChris Craik        return;
138ba9b613437c34873fa95800a25fc51720638267cChris Craik    }
139ba9b613437c34873fa95800a25fc51720638267cChris Craik
140ba9b613437c34873fa95800a25fc51720638267cChris Craik    if (name == NULL || value == NULL) {
141ba9b613437c34873fa95800a25fc51720638267cChris Craik        ALOGW("can't set prop, null passed");
142ba9b613437c34873fa95800a25fc51720638267cChris Craik    }
143ba9b613437c34873fa95800a25fc51720638267cChris Craik
144ba9b613437c34873fa95800a25fc51720638267cChris Craik    const char* nameCharArray = env->GetStringUTFChars(name, NULL);
145ba9b613437c34873fa95800a25fc51720638267cChris Craik    const char* valueCharArray = env->GetStringUTFChars(value, NULL);
146ba9b613437c34873fa95800a25fc51720638267cChris Craik    Caches::getInstance().setTempProperty(nameCharArray, valueCharArray);
147ba9b613437c34873fa95800a25fc51720638267cChris Craik    env->ReleaseStringUTFChars(name, nameCharArray);
148ba9b613437c34873fa95800a25fc51720638267cChris Craik    env->ReleaseStringUTFChars(name, valueCharArray);
149ba9b613437c34873fa95800a25fc51720638267cChris Craik}
150ba9b613437c34873fa95800a25fc51720638267cChris Craik
151530041d3191ce817832a0108514617768e43cda6Romain Guy// ----------------------------------------------------------------------------
152530041d3191ce817832a0108514617768e43cda6Romain Guy// Functor
153530041d3191ce817832a0108514617768e43cda6Romain Guy// ----------------------------------------------------------------------------
154530041d3191ce817832a0108514617768e43cda6Romain Guy
1556554943a1dd6854c0f4976900956e556767b49e1Romain Guystatic jint android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
15636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong functorPtr) {
1573b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
1589f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    Functor* functor = reinterpret_cast<Functor*>(functorPtr);
159cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    android::uirenderer::Rect dirty;
160cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    return renderer->callDrawGLFunction(functor, dirty);
161daf98e941e140e8739458126640183b9f296a2abChet Haase}
162daf98e941e140e8739458126640183b9f296a2abChet Haase
1638f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy// ----------------------------------------------------------------------------
1648f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy// Misc
1658f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy// ----------------------------------------------------------------------------
1668f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy
167f61970fc79e9c5cf340fa942597628242361864aRomain Guystatic jint android_view_GLES20Canvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) {
168f61970fc79e9c5cf340fa942597628242361864aRomain Guy    return Caches::getInstance().maxTextureSize;
169f61970fc79e9c5cf340fa942597628242361864aRomain Guy}
170f61970fc79e9c5cf340fa942597628242361864aRomain Guy
171f61970fc79e9c5cf340fa942597628242361864aRomain Guystatic jint android_view_GLES20Canvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) {
172f61970fc79e9c5cf340fa942597628242361864aRomain Guy    return Caches::getInstance().maxTextureSize;
173f61970fc79e9c5cf340fa942597628242361864aRomain Guy}
174f61970fc79e9c5cf340fa942597628242361864aRomain Guy
175e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
176bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// State
177bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// ----------------------------------------------------------------------------
178bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
17936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, jlong rendererPtr,
180bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        jint flags) {
1813b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
182f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    return renderer->save(flags);
183f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
184bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1857d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz,
18636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
1873b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
188f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    return renderer->getSaveCount();
189bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
190bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1917d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz,
19236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
1933b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
194f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    renderer->restore();
195bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
196bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1977d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz,
19836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint saveCount) {
1993b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
200f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    renderer->restoreToCount(saveCount);
201bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
202bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
203f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// ----------------------------------------------------------------------------
204bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy// Layers
205bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy// ----------------------------------------------------------------------------
206bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
2077d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz,
20836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
20936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong paintPtr, jint saveFlags) {
2103b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
2116ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
212bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
213bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy}
214bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
215189887e0ae171c1b7601991442104a30e56c50abRomain Guystatic jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz,
21636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong paintPtr, jint saveFlags) {
2173b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
2186ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
2193f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik    const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
220189887e0ae171c1b7601991442104a30e56c50abRomain Guy    return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
221189887e0ae171c1b7601991442104a30e56c50abRomain Guy            paint, saveFlags);
222189887e0ae171c1b7601991442104a30e56c50abRomain Guy}
223189887e0ae171c1b7601991442104a30e56c50abRomain Guy
2247d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz,
22536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
226bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        jint alpha, jint saveFlags) {
2273b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
228bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
229bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy}
230bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
231189887e0ae171c1b7601991442104a30e56c50abRomain Guystatic jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz,
23236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint alpha, jint saveFlags) {
2333b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
2343f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik    const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
235189887e0ae171c1b7601991442104a30e56c50abRomain Guy    return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
236189887e0ae171c1b7601991442104a30e56c50abRomain Guy            alpha, saveFlags);
237189887e0ae171c1b7601991442104a30e56c50abRomain Guy}
238189887e0ae171c1b7601991442104a30e56c50abRomain Guy
239bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy// ----------------------------------------------------------------------------
240f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Clipping
241f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// ----------------------------------------------------------------------------
242f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
24336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
24436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom) {
2453b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
24636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->quickRejectConservative(left, top, right, bottom);
24736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
248c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy}
249c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
25036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
25136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
25236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jint op) {
2533b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
25436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->clipRect(left, top, right, bottom,
25536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                           static_cast<SkRegion::Op>(op));
25636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
257f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
258bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
25936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz,
26036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint left, jint top, jint right, jint bottom,
26136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jint op) {
2623b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
26336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->clipRect(float(left), float(top), float(right),
26436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                           float(bottom),
26536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                           static_cast<SkRegion::Op>(op));
26636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
267bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
268bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
26936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_clipPath(JNIEnv* env, jobject clazz,
27036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong pathPtr, jint op) {
2713b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
2729f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
27336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->clipPath(path, static_cast<SkRegion::Op>(op));
27436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
275735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy}
276735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
27736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz,
27836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong regionPtr, jint op) {
2793b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
2809f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
28136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->clipRegion(region, static_cast<SkRegion::Op>(op));
28236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
283735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy}
284735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
28536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
28636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jobject rect) {
2873b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
2883f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik    const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
2899d5316e3f56d138504565ff311145ac01621dff4Romain Guy
2907ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    env->CallVoidMethod(rect, gRectClassInfo.set,
2917ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
2929d5316e3f56d138504565ff311145ac01621dff4Romain Guy
29336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return !bounds.isEmpty() ? JNI_TRUE : JNI_FALSE;
2949d5316e3f56d138504565ff311145ac01621dff4Romain Guy}
2959d5316e3f56d138504565ff311145ac01621dff4Romain Guy
296bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// ----------------------------------------------------------------------------
297f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Transforms
298bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// ----------------------------------------------------------------------------
299bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3007d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz,
30136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat dx, jfloat dy) {
3023b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3037ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    renderer->translate(dx, dy);
304f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
305bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3067d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz,
30736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat degrees) {
3083b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3097ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    renderer->rotate(degrees);
310bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
311bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3127d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz,
31336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat sx, jfloat sy) {
3143b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3157ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    renderer->scale(sx, sy);
316f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
317bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3187d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz,
31936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat sx, jfloat sy) {
3203b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
321807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy    renderer->skew(sx, sy);
322807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy}
323807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy
3247d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz,
32536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong matrixPtr) {
3263b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3279f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
328139088228faa7f3c446af7387e017933998a5570Derek Sollenberger    renderer->setMatrix(matrix ? *matrix : SkMatrix::I());
329f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
330f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
3317d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz,
33236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong matrixPtr) {
3333b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3349f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
3357ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    renderer->getMatrix(matrix);
336f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
337f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
3387d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
33936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong matrixPtr) {
3403b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3419f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
342139088228faa7f3c446af7387e017933998a5570Derek Sollenberger    renderer->concatMatrix(*matrix);
343bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
344bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
345bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// ----------------------------------------------------------------------------
346bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// Drawing
34785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy// ----------------------------------------------------------------------------
34885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
3497d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
350f29d5a5b211786248d0557157c304c5fff428bd4Derek Sollenberger        jlong rendererPtr, jlong bitmapPtr, jfloat left, jfloat top, jlong paintPtr) {
3519f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
3520c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
3533b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3546ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
355796475006f5d670e8383a2050f11719522437a43Chris Craik
356796475006f5d670e8383a2050f11719522437a43Chris Craik    // apply transform directly to canvas, so it affects shaders correctly
357796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->save(SkCanvas::kMatrix_SaveFlag);
358796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->translate(left, top);
359796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->drawBitmap(bitmap, paint);
360796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->restore();
361ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
362ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
3637d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
364f29d5a5b211786248d0557157c304c5fff428bd4Derek Sollenberger        jlong rendererPtr, jlong bitmapPtr,
365ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        float srcLeft, float srcTop, float srcRight, float srcBottom,
36636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) {
3679f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
3680c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
3693b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3706ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
371dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy    renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
372dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy            dstLeft, dstTop, dstRight, dstBottom, paint);
373f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy}
3748ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy
3757d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
376f29d5a5b211786248d0557157c304c5fff428bd4Derek Sollenberger        jlong rendererPtr, jlong bitmapPtr, jlong matrixPtr, jlong paintPtr) {
3779f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
3780c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
3793b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
3809f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
3816ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
382796475006f5d670e8383a2050f11719522437a43Chris Craik
383796475006f5d670e8383a2050f11719522437a43Chris Craik    // apply transform directly to canvas, so it affects shaders correctly
384796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->save(SkCanvas::kMatrix_SaveFlag);
385796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->concatMatrix(*matrix);
386796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->drawBitmap(bitmap, paint);
387796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->restore();
388ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
389ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
390e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guystatic void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
39136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jintArray colors, jint offset, jint stride,
39236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) {
39357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will
39457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    // correct the alphaType to kOpaque_SkAlphaType.
395b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed    const SkImageInfo info = SkImageInfo::Make(width, height,
396b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed                               hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType,
397b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed                               kPremul_SkAlphaType);
39849c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    SkBitmap* bitmap = new SkBitmap;
399b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed    if (!bitmap->allocPixels(info)) {
40049c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy        delete bitmap;
401e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy        return;
402e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy    }
403e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy
40457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap)) {
40549c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy        delete bitmap;
406e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy        return;
407e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy    }
408e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy
4093b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
4106ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
411796475006f5d670e8383a2050f11719522437a43Chris Craik
412796475006f5d670e8383a2050f11719522437a43Chris Craik    // apply transform directly to canvas, so it affects shaders correctly
413796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->save(SkCanvas::kMatrix_SaveFlag);
414796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->translate(left, top);
415796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->drawBitmapData(bitmap, paint);
416796475006f5d670e8383a2050f11719522437a43Chris Craik    renderer->restore();
41749c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy
418f23b25abfb76e75f63103abc882bc91b8327a957Chris Craik    // Note - bitmap isn't deleted as DisplayListRenderer owns it now
419e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy}
420e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy
4217d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
422f29d5a5b211786248d0557157c304c5fff428bd4Derek Sollenberger        jlong rendererPtr, jlong bitmapPtr, jint meshWidth, jint meshHeight,
423f29d5a5b211786248d0557157c304c5fff428bd4Derek Sollenberger        jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, jlong paintPtr) {
4249f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
4250c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
4265a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
4275a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
4285a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
4293b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
4306ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
4315a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint);
4325a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
4335a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0);
4345a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0);
4355a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy}
4365a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
4377d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
438f29d5a5b211786248d0557157c304c5fff428bd4Derek Sollenberger        jlong rendererPtr, jlong bitmapPtr, jlong patchPtr,
43936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        float left, float top, float right, float bottom, jlong paintPtr) {
4409f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
4410c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
4423b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
4439f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr);
4446ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
4453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
446deba785f122a47915756ffd991f5540d952cf937Romain Guy}
447deba785f122a47915756ffd991f5540d952cf937Romain Guy
4487d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz,
4492ce932832e7caa1a6021539a9b7828ee5f49a610Chris Craik        jlong rendererPtr, jint color, jint modeHandle) {
4503b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
4512ce932832e7caa1a6021539a9b7828ee5f49a610Chris Craik    SkPorterDuff::Mode mode = static_cast<SkPorterDuff::Mode>(modeHandle);
4522ce932832e7caa1a6021539a9b7828ee5f49a610Chris Craik    renderer->drawColor(color, SkPorterDuff::ToXfermodeMode(mode));
45385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy}
45485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
4557d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz,
45636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
45736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong paintPtr) {
4583b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
4596ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
460c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy    renderer->drawRect(left, top, right, bottom, paint);
461c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy}
462c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
4637d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz,
46436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
46536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloat rx, jfloat ry, jlong paintPtr) {
4663b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
4676ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
46801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
46901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
47001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
471072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggistatic void android_view_GLES20Canvas_drawRoundRectProps(JNIEnv* env, jobject clazz,
472072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        jlong rendererPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
473072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi        jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
474072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
475072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
476072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
477072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
478072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr);
479072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr);
480072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr);
481072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
482072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi    renderer->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
483072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi}
484072707dfad1da6f49f4d3ce58ca104f6c46a7266Jorim Jaggi
4857d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
48636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) {
4873b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
4886ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
48901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    renderer->drawCircle(x, y, radius, paint);
49001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
49101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
49252244fff29042926e21fa897ef5ab11148e35299John Reckstatic void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz,
49352244fff29042926e21fa897ef5ab11148e35299John Reck        jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
4943b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
49552244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
49652244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
49752244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
49852244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
49952244fff29042926e21fa897ef5ab11148e35299John Reck    renderer->drawCircle(xProp, yProp, radiusProp, paintProp);
50052244fff29042926e21fa897ef5ab11148e35299John Reck}
50152244fff29042926e21fa897ef5ab11148e35299John Reck
5027d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz,
50336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
50436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong paintPtr) {
5053b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
5066ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
507c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    renderer->drawOval(left, top, right, bottom, paint);
508c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}
509c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
5107d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz,
51136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
51236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) {
5133b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
5146ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
5158b2f5267f16c295f12faab810527cd6311997e34Romain Guy    renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
5168b2f5267f16c295f12faab810527cd6311997e34Romain Guy}
5178b2f5267f16c295f12faab810527cd6311997e34Romain Guy
518672433d90fab7383cd28beac9d4485b566a90940Romain Guystatic void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz,
51936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong regionPtr, jlong paintPtr) {
5203b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
5219f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
5226ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
5236ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    if (paint->getStyle() != Paint::kFill_Style ||
524672433d90fab7383cd28beac9d4485b566a90940Romain Guy            (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) {
525672433d90fab7383cd28beac9d4485b566a90940Romain Guy        SkRegion::Iterator it(*region);
526672433d90fab7383cd28beac9d4485b566a90940Romain Guy        while (!it.done()) {
527672433d90fab7383cd28beac9d4485b566a90940Romain Guy            const SkIRect& r = it.rect();
528672433d90fab7383cd28beac9d4485b566a90940Romain Guy            renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
529672433d90fab7383cd28beac9d4485b566a90940Romain Guy            it.next();
530672433d90fab7383cd28beac9d4485b566a90940Romain Guy        }
531672433d90fab7383cd28beac9d4485b566a90940Romain Guy    } else {
532672433d90fab7383cd28beac9d4485b566a90940Romain Guy        int count = 0;
533672433d90fab7383cd28beac9d4485b566a90940Romain Guy        Vector<float> rects;
534672433d90fab7383cd28beac9d4485b566a90940Romain Guy        SkRegion::Iterator it(*region);
535672433d90fab7383cd28beac9d4485b566a90940Romain Guy        while (!it.done()) {
536672433d90fab7383cd28beac9d4485b566a90940Romain Guy            const SkIRect& r = it.rect();
537672433d90fab7383cd28beac9d4485b566a90940Romain Guy            rects.push(r.fLeft);
538672433d90fab7383cd28beac9d4485b566a90940Romain Guy            rects.push(r.fTop);
539672433d90fab7383cd28beac9d4485b566a90940Romain Guy            rects.push(r.fRight);
540672433d90fab7383cd28beac9d4485b566a90940Romain Guy            rects.push(r.fBottom);
5412af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            count += 4;
542672433d90fab7383cd28beac9d4485b566a90940Romain Guy            it.next();
543672433d90fab7383cd28beac9d4485b566a90940Romain Guy        }
544672433d90fab7383cd28beac9d4485b566a90940Romain Guy        renderer->drawRects(rects.array(), count, paint);
545a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy    }
546a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy}
547a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy
548ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guystatic void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz,
54936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
5503b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
551ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy    jfloat* storage = env->GetFloatArrayElements(points, NULL);
5526ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
553ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy    renderer->drawPoints(storage + offset, count, paint);
554ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy    env->ReleaseFloatArrayElements(points, storage, 0);
555ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy}
556ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy
5577d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
55836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong pathPtr, jlong paintPtr) {
5593b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
5609f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
5616ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
5627fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy    renderer->drawPath(path, paint);
5637fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy}
5647fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy
5657d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
56636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
5673b20251a355c88193c439f928a84ae69483fb488John Reck    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
568759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    jfloat* storage = env->GetFloatArrayElements(points, NULL);
5696ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod    Paint* paint = reinterpret_cast<Paint*>(paintPtr);
570759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    renderer->drawLines(storage + offset, count, paint);
571759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    env->ReleaseFloatArrayElements(points, storage, 0);
572759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy}
573759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy
57485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy// ----------------------------------------------------------------------------
5755ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy// Draw filters
5765ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy// ----------------------------------------------------------------------------
577