android_view_GLES20Canvas.cpp revision d27977d1a91d5a6b3cc9fa7664ac7e835e7bd895
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "jni.h" 18#include <nativehelper/JNIHelp.h> 19#include <android_runtime/AndroidRuntime.h> 20#include <utils/ResourceTypes.h> 21 22#include <SkBitmap.h> 23#include <SkCanvas.h> 24#include <SkMatrix.h> 25#include <SkPaint.h> 26#include <SkXfermode.h> 27 28#include <OpenGLRenderer.h> 29#include <Rect.h> 30#include <ui/Rect.h> 31 32namespace android { 33 34using namespace uirenderer; 35 36// ---------------------------------------------------------------------------- 37// Java APIs 38// ---------------------------------------------------------------------------- 39 40static struct { 41 jclass clazz; 42 jmethodID set; 43} gRectClassInfo; 44 45// ---------------------------------------------------------------------------- 46// Constructors 47// ---------------------------------------------------------------------------- 48 49static OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject canvas) { 50 return new OpenGLRenderer; 51} 52 53static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject canvas, 54 OpenGLRenderer* renderer) { 55 delete renderer; 56} 57 58// ---------------------------------------------------------------------------- 59// Setup 60// ---------------------------------------------------------------------------- 61 62static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject canvas, 63 OpenGLRenderer* renderer, jint width, jint height) { 64 renderer->setViewport(width, height); 65} 66 67static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas, 68 OpenGLRenderer* renderer) { 69 renderer->prepare(); 70} 71 72// ---------------------------------------------------------------------------- 73// State 74// ---------------------------------------------------------------------------- 75 76static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, 77 jint flags) { 78 return renderer->save(flags); 79} 80 81static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject canvas, 82 OpenGLRenderer* renderer) { 83 return renderer->getSaveCount(); 84} 85 86static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject canvas, 87 OpenGLRenderer* renderer) { 88 renderer->restore(); 89} 90 91static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas, 92 OpenGLRenderer* renderer, jint saveCount) { 93 renderer->restoreToCount(saveCount); 94} 95 96// ---------------------------------------------------------------------------- 97// Layers 98// ---------------------------------------------------------------------------- 99 100static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject canvas, 101 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, 102 SkPaint* paint, jint saveFlags) { 103 return renderer->saveLayer(left, top, right, bottom, paint, saveFlags); 104} 105 106static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas, 107 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, 108 jint alpha, jint saveFlags) { 109 return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags); 110} 111 112// ---------------------------------------------------------------------------- 113// Clipping 114// ---------------------------------------------------------------------------- 115 116static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject canvas, 117 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, 118 SkCanvas::EdgeType edge) { 119 return renderer->quickReject(left, top, right, bottom); 120} 121 122static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject canvas, 123 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) { 124 return renderer->clipRect(left, top, right, bottom); 125} 126 127static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject canvas, 128 OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom) { 129 return renderer->clipRect(float(left), float(top), float(right), float(bottom)); 130} 131 132static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas, 133 OpenGLRenderer* renderer, jobject rect) { 134 const android::uirenderer::Rect& bounds(renderer->getClipBounds()); 135 136 env->CallVoidMethod(rect, gRectClassInfo.set, 137 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); 138 139 return !bounds.isEmpty(); 140} 141 142// ---------------------------------------------------------------------------- 143// Transforms 144// ---------------------------------------------------------------------------- 145 146static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject canvas, 147 OpenGLRenderer* renderer, jfloat dx, jfloat dy) { 148 renderer->translate(dx, dy); 149} 150 151static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject canvas, 152 OpenGLRenderer* renderer, jfloat degrees) { 153 renderer->rotate(degrees); 154} 155 156static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject canvas, 157 OpenGLRenderer* renderer, jfloat sx, jfloat sy) { 158 renderer->scale(sx, sy); 159} 160 161static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject canvas, 162 OpenGLRenderer* renderer, SkMatrix* matrix) { 163 renderer->setMatrix(matrix); 164} 165 166static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject canvas, 167 OpenGLRenderer* renderer, SkMatrix* matrix) { 168 renderer->getMatrix(matrix); 169} 170 171static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas, 172 OpenGLRenderer* renderer, SkMatrix* matrix) { 173 renderer->concatMatrix(matrix); 174} 175 176// ---------------------------------------------------------------------------- 177// Drawing 178// ---------------------------------------------------------------------------- 179 180static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject canvas, 181 OpenGLRenderer* renderer, SkBitmap* bitmap, float left, float top, SkPaint* paint) { 182 renderer->drawBitmap(bitmap, left, top, paint); 183} 184 185static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject canvas, 186 OpenGLRenderer* renderer, SkBitmap* bitmap, 187 float srcLeft, float srcTop, float srcRight, float srcBottom, 188 float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) { 189 renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, 190 dstLeft, dstTop, dstRight, dstBottom, paint); 191} 192 193static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject canvas, 194 OpenGLRenderer* renderer, SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { 195 renderer->drawBitmap(bitmap, matrix, paint); 196} 197 198static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas, 199 OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray chunks, 200 float left, float top, float right, float bottom, SkPaint* paint) { 201 202 jbyte* storage = env->GetByteArrayElements(chunks, NULL); 203 Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage); 204 Res_png_9patch::deserialize(patch); 205 206 renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint); 207 208 // TODO: make sure that 0 is correct for the flags 209 env->ReleaseByteArrayElements(chunks, storage, 0); 210} 211 212static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject canvas, 213 OpenGLRenderer* renderer, jint color, SkXfermode::Mode mode) { 214 renderer->drawColor(color, mode); 215} 216 217static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas, 218 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, 219 SkPaint* paint) { 220 renderer->drawRect(left, top, right, bottom, paint); 221} 222 223// ---------------------------------------------------------------------------- 224// Shaders 225// ---------------------------------------------------------------------------- 226 227static void android_view_GLES20Canvas_resetShader(JNIEnv* env, jobject canvas, 228 OpenGLRenderer* renderer) { 229 renderer->resetShader(); 230} 231 232static void android_view_GLES20Canvas_setupBitmapShader(JNIEnv* env, jobject canvas, 233 OpenGLRenderer* renderer, SkShader* shader, SkBitmap* bitmap, 234 SkShader::TileMode tileX, SkShader::TileMode tileY, SkMatrix* matrix) { 235 renderer->setupBitmapShader(bitmap, tileX, tileY, matrix, 236 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0); 237} 238 239// ---------------------------------------------------------------------------- 240// JNI Glue 241// ---------------------------------------------------------------------------- 242 243const char* const kClassPathName = "android/view/GLES20Canvas"; 244 245static JNINativeMethod gMethods[] = { 246 { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer }, 247 { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer }, 248 { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport }, 249 { "nPrepare", "(I)V", (void*) android_view_GLES20Canvas_prepare }, 250 251 { "nSave", "(II)I", (void*) android_view_GLES20Canvas_save }, 252 { "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore }, 253 { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Canvas_restoreToCount }, 254 { "nGetSaveCount", "(I)I", (void*) android_view_GLES20Canvas_getSaveCount }, 255 256 { "nSaveLayer", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayer }, 257 { "nSaveLayerAlpha", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha }, 258 259 { "nQuickReject", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_quickReject }, 260 { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Canvas_clipRectF }, 261 { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Canvas_clipRect }, 262 263 { "nTranslate", "(IFF)V", (void*) android_view_GLES20Canvas_translate }, 264 { "nRotate", "(IF)V", (void*) android_view_GLES20Canvas_rotate }, 265 { "nScale", "(IFF)V", (void*) android_view_GLES20Canvas_scale }, 266 267 { "nSetMatrix", "(II)V", (void*) android_view_GLES20Canvas_setMatrix }, 268 { "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix }, 269 { "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix }, 270 271 { "nDrawBitmap", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawBitmap }, 272 { "nDrawBitmap", "(IIFFFFFFFFI)V", (void*) android_view_GLES20Canvas_drawBitmapRect }, 273 { "nDrawBitmap", "(IIII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, 274 { "nDrawPatch", "(II[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch }, 275 { "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor }, 276 { "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect }, 277 278 { "nResetShader", "(I)V", (void*) android_view_GLES20Canvas_resetShader }, 279 { "nSetupBitmapShader", "(IIIIII)V", (void*) android_view_GLES20Canvas_setupBitmapShader }, 280 281 { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z", 282 (void*) android_view_GLES20Canvas_getClipBounds }, 283}; 284 285#define FIND_CLASS(var, className) \ 286 var = env->FindClass(className); \ 287 LOG_FATAL_IF(! var, "Unable to find class " className); \ 288 var = jclass(env->NewGlobalRef(var)); 289 290#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 291 var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 292 LOG_FATAL_IF(! var, "Unable to find method " methodName); 293 294int register_android_view_GLES20Canvas(JNIEnv* env) { 295 FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect"); 296 GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V"); 297 298 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 299} 300 301}; 302