android_view_Surface.cpp revision 289b9b62372ef52a06113b83dfb870e2c2fb325a
1/* 2 * Copyright (C) 2007 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#define LOG_TAG "Surface" 18 19#include <stdio.h> 20 21#include "android_util_Binder.h" 22 23#include <surfaceflinger/SurfaceComposerClient.h> 24#include <surfaceflinger/Surface.h> 25#include <ui/Region.h> 26#include <ui/Rect.h> 27 28#include <EGL/egl.h> 29 30#include <SkCanvas.h> 31#include <SkBitmap.h> 32#include <SkRegion.h> 33 34#include "jni.h" 35#include <android_runtime/AndroidRuntime.h> 36#include <android_runtime/android_view_Surface.h> 37#include <utils/misc.h> 38 39 40// ---------------------------------------------------------------------------- 41 42namespace android { 43 44enum { 45 // should match Parcelable.java 46 PARCELABLE_WRITE_RETURN_VALUE = 0x0001 47}; 48 49// ---------------------------------------------------------------------------- 50 51static const char* const OutOfResourcesException = 52 "android/view/Surface$OutOfResourcesException"; 53 54struct sso_t { 55 jfieldID client; 56}; 57static sso_t sso; 58 59struct so_t { 60 jfieldID surfaceControl; 61 jfieldID surface; 62 jfieldID saveCount; 63 jfieldID canvas; 64}; 65static so_t so; 66 67struct ro_t { 68 jfieldID l; 69 jfieldID t; 70 jfieldID r; 71 jfieldID b; 72}; 73static ro_t ro; 74 75struct po_t { 76 jfieldID x; 77 jfieldID y; 78}; 79static po_t po; 80 81struct co_t { 82 jfieldID surfaceFormat; 83}; 84static co_t co; 85 86struct no_t { 87 jfieldID native_canvas; 88 jfieldID native_region; 89 jfieldID native_parcel; 90}; 91static no_t no; 92 93 94static __attribute__((noinline)) 95void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) 96{ 97 if (!env->ExceptionOccurred()) { 98 jclass npeClazz = env->FindClass(exc); 99 env->ThrowNew(npeClazz, msg); 100 } 101} 102 103// ---------------------------------------------------------------------------- 104// ---------------------------------------------------------------------------- 105// ---------------------------------------------------------------------------- 106 107static void SurfaceSession_init(JNIEnv* env, jobject clazz) 108{ 109 sp<SurfaceComposerClient> client = new SurfaceComposerClient; 110 client->incStrong(clazz); 111 env->SetIntField(clazz, sso.client, (int)client.get()); 112} 113 114static void SurfaceSession_destroy(JNIEnv* env, jobject clazz) 115{ 116 SurfaceComposerClient* client = 117 (SurfaceComposerClient*)env->GetIntField(clazz, sso.client); 118 if (client != 0) { 119 client->decStrong(clazz); 120 env->SetIntField(clazz, sso.client, 0); 121 } 122} 123 124static void SurfaceSession_kill(JNIEnv* env, jobject clazz) 125{ 126 SurfaceComposerClient* client = 127 (SurfaceComposerClient*)env->GetIntField(clazz, sso.client); 128 if (client != 0) { 129 client->dispose(); 130 client->decStrong(clazz); 131 env->SetIntField(clazz, sso.client, 0); 132 } 133} 134 135// ---------------------------------------------------------------------------- 136 137static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject clazz) 138{ 139 SurfaceControl* const p = 140 (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); 141 return sp<SurfaceControl>(p); 142} 143 144static void setSurfaceControl(JNIEnv* env, jobject clazz, 145 const sp<SurfaceControl>& surface) 146{ 147 SurfaceControl* const p = 148 (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); 149 if (surface.get()) { 150 surface->incStrong(clazz); 151 } 152 if (p) { 153 p->decStrong(clazz); 154 } 155 env->SetIntField(clazz, so.surfaceControl, (int)surface.get()); 156} 157 158static sp<Surface> getSurface(JNIEnv* env, jobject clazz) 159{ 160 sp<Surface> result((Surface*)env->GetIntField(clazz, so.surface)); 161 if (result == 0) { 162 /* 163 * if this method is called from the WindowManager's process, it means 164 * the client is is not remote, and therefore is allowed to have 165 * a Surface (data), so we create it here. 166 * If we don't have a SurfaceControl, it means we're in a different 167 * process. 168 */ 169 170 SurfaceControl* const control = 171 (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); 172 if (control) { 173 result = control->getSurface(); 174 if (result != 0) { 175 result->incStrong(clazz); 176 env->SetIntField(clazz, so.surface, (int)result.get()); 177 } 178 } 179 } 180 return result; 181} 182 183sp<ANativeWindow> android_Surface_getNativeWindow( 184 JNIEnv* env, jobject clazz) { 185 return getSurface(env, clazz).get(); 186} 187 188static void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface) 189{ 190 Surface* const p = (Surface*)env->GetIntField(clazz, so.surface); 191 if (surface.get()) { 192 surface->incStrong(clazz); 193 } 194 if (p) { 195 p->decStrong(clazz); 196 } 197 env->SetIntField(clazz, so.surface, (int)surface.get()); 198} 199 200// ---------------------------------------------------------------------------- 201 202static void Surface_init( 203 JNIEnv* env, jobject clazz, 204 jobject session, 205 jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jint flags) 206{ 207 if (session == NULL) { 208 doThrow(env, "java/lang/NullPointerException"); 209 return; 210 } 211 212 SurfaceComposerClient* client = 213 (SurfaceComposerClient*)env->GetIntField(session, sso.client); 214 215 sp<SurfaceControl> surface; 216 if (jname == NULL) { 217 surface = client->createSurface(pid, dpy, w, h, format, flags); 218 } else { 219 const jchar* str = env->GetStringCritical(jname, 0); 220 const String8 name(str, env->GetStringLength(jname)); 221 env->ReleaseStringCritical(jname, str); 222 surface = client->createSurface(pid, name, dpy, w, h, format, flags); 223 } 224 225 if (surface == 0) { 226 doThrow(env, OutOfResourcesException); 227 return; 228 } 229 setSurfaceControl(env, clazz, surface); 230} 231 232static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel) 233{ 234 Parcel* parcel = (Parcel*)env->GetIntField(argParcel, no.native_parcel); 235 if (parcel == NULL) { 236 doThrow(env, "java/lang/NullPointerException", NULL); 237 return; 238 } 239 240 sp<Surface> sur(Surface::readFromParcel(*parcel, 0)); 241 setSurface(env, clazz, sur); 242} 243 244static jint Surface_getIdentity(JNIEnv* env, jobject clazz) 245{ 246 const sp<SurfaceControl>& control(getSurfaceControl(env, clazz)); 247 if (control != 0) return (jint) control->getIdentity(); 248 const sp<Surface>& surface(getSurface(env, clazz)); 249 if (surface != 0) return (jint) surface->getIdentity(); 250 return -1; 251} 252 253static void Surface_destroy(JNIEnv* env, jobject clazz, uintptr_t *ostack) 254{ 255 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 256 if (SurfaceControl::isValid(surface)) { 257 surface->clear(); 258 } 259 setSurfaceControl(env, clazz, 0); 260 setSurface(env, clazz, 0); 261} 262 263static void Surface_release(JNIEnv* env, jobject clazz, uintptr_t *ostack) 264{ 265 setSurfaceControl(env, clazz, 0); 266 setSurface(env, clazz, 0); 267} 268 269static jboolean Surface_isValid(JNIEnv* env, jobject clazz) 270{ 271 const sp<SurfaceControl>& surfaceControl(getSurfaceControl(env, clazz)); 272 if (surfaceControl != 0) { 273 return SurfaceControl::isValid(surfaceControl) ? JNI_TRUE : JNI_FALSE; 274 } 275 const sp<Surface>& surface(getSurface(env, clazz)); 276 return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE; 277} 278 279static inline SkBitmap::Config convertPixelFormat(PixelFormat format) 280{ 281 /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then 282 we can map to SkBitmap::kARGB_8888_Config, and optionally call 283 bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator) 284 */ 285 switch (format) { 286 case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config; 287 case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config; 288 case PIXEL_FORMAT_RGBA_4444: return SkBitmap::kARGB_4444_Config; 289 case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config; 290 case PIXEL_FORMAT_A_8: return SkBitmap::kA8_Config; 291 default: return SkBitmap::kNo_Config; 292 } 293} 294 295static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) 296{ 297 const sp<Surface>& surface(getSurface(env, clazz)); 298 if (!Surface::isValid(surface)) 299 return 0; 300 301 // get dirty region 302 Region dirtyRegion; 303 if (dirtyRect) { 304 Rect dirty; 305 dirty.left = env->GetIntField(dirtyRect, ro.l); 306 dirty.top = env->GetIntField(dirtyRect, ro.t); 307 dirty.right = env->GetIntField(dirtyRect, ro.r); 308 dirty.bottom= env->GetIntField(dirtyRect, ro.b); 309 if (!dirty.isEmpty()) { 310 dirtyRegion.set(dirty); 311 } 312 } else { 313 dirtyRegion.set(Rect(0x3FFF,0x3FFF)); 314 } 315 316 Surface::SurfaceInfo info; 317 status_t err = surface->lock(&info, &dirtyRegion); 318 if (err < 0) { 319 const char* const exception = (err == NO_MEMORY) ? 320 OutOfResourcesException : 321 "java/lang/IllegalArgumentException"; 322 doThrow(env, exception, NULL); 323 return 0; 324 } 325 326 // Associate a SkCanvas object to this surface 327 jobject canvas = env->GetObjectField(clazz, so.canvas); 328 env->SetIntField(canvas, co.surfaceFormat, info.format); 329 330 SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas); 331 SkBitmap bitmap; 332 ssize_t bpr = info.s * bytesPerPixel(info.format); 333 bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr); 334 if (info.format == PIXEL_FORMAT_RGBX_8888) { 335 bitmap.setIsOpaque(true); 336 } 337 if (info.w > 0 && info.h > 0) { 338 bitmap.setPixels(info.bits); 339 } else { 340 // be safe with an empty bitmap. 341 bitmap.setPixels(NULL); 342 } 343 nativeCanvas->setBitmapDevice(bitmap); 344 345 SkRegion clipReg; 346 if (dirtyRegion.isRect()) { // very common case 347 const Rect b(dirtyRegion.getBounds()); 348 clipReg.setRect(b.left, b.top, b.right, b.bottom); 349 } else { 350 size_t count; 351 Rect const* r = dirtyRegion.getArray(&count); 352 while (count) { 353 clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op); 354 r++, count--; 355 } 356 } 357 358 nativeCanvas->clipRegion(clipReg); 359 360 int saveCount = nativeCanvas->save(); 361 env->SetIntField(clazz, so.saveCount, saveCount); 362 363 if (dirtyRect) { 364 const Rect& bounds(dirtyRegion.getBounds()); 365 env->SetIntField(dirtyRect, ro.l, bounds.left); 366 env->SetIntField(dirtyRect, ro.t, bounds.top); 367 env->SetIntField(dirtyRect, ro.r, bounds.right); 368 env->SetIntField(dirtyRect, ro.b, bounds.bottom); 369 } 370 371 return canvas; 372} 373 374static void Surface_unlockCanvasAndPost( 375 JNIEnv* env, jobject clazz, jobject argCanvas) 376{ 377 jobject canvas = env->GetObjectField(clazz, so.canvas); 378 if (canvas != argCanvas) { 379 doThrow(env, "java/lang/IllegalArgumentException", NULL); 380 return; 381 } 382 383 const sp<Surface>& surface(getSurface(env, clazz)); 384 if (!Surface::isValid(surface)) 385 return; 386 387 // detach the canvas from the surface 388 SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas); 389 int saveCount = env->GetIntField(clazz, so.saveCount); 390 nativeCanvas->restoreToCount(saveCount); 391 nativeCanvas->setBitmapDevice(SkBitmap()); 392 env->SetIntField(clazz, so.saveCount, 0); 393 394 // unlock surface 395 status_t err = surface->unlockAndPost(); 396 if (err < 0) { 397 doThrow(env, "java/lang/IllegalArgumentException", NULL); 398 } 399} 400 401static void Surface_unlockCanvas( 402 JNIEnv* env, jobject clazz, jobject argCanvas) 403{ 404 // XXX: this API has been removed 405 doThrow(env, "java/lang/IllegalArgumentException", NULL); 406} 407 408static void Surface_openTransaction( 409 JNIEnv* env, jobject clazz) 410{ 411 SurfaceComposerClient::openGlobalTransaction(); 412} 413 414static void Surface_closeTransaction( 415 JNIEnv* env, jobject clazz) 416{ 417 SurfaceComposerClient::closeGlobalTransaction(); 418} 419 420static void Surface_setOrientation( 421 JNIEnv* env, jobject clazz, jint display, jint orientation, jint flags) 422{ 423 int err = SurfaceComposerClient::setOrientation(display, orientation, flags); 424 if (err < 0) { 425 doThrow(env, "java/lang/IllegalArgumentException", NULL); 426 } 427} 428 429static void Surface_freezeDisplay( 430 JNIEnv* env, jobject clazz, jint display) 431{ 432 int err = SurfaceComposerClient::freezeDisplay(display, 0); 433 if (err < 0) { 434 doThrow(env, "java/lang/IllegalArgumentException", NULL); 435 } 436} 437 438static void Surface_unfreezeDisplay( 439 JNIEnv* env, jobject clazz, jint display) 440{ 441 int err = SurfaceComposerClient::unfreezeDisplay(display, 0); 442 if (err < 0) { 443 doThrow(env, "java/lang/IllegalArgumentException", NULL); 444 } 445} 446 447static void Surface_setLayer( 448 JNIEnv* env, jobject clazz, jint zorder) 449{ 450 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 451 if (surface == 0) return; 452 status_t err = surface->setLayer(zorder); 453 if (err<0 && err!=NO_INIT) 454 doThrow(env, "java/lang/IllegalArgumentException", NULL); 455} 456 457static void Surface_setPosition( 458 JNIEnv* env, jobject clazz, jint x, jint y) 459{ 460 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 461 if (surface == 0) return; 462 status_t err = surface->setPosition(x, y); 463 if (err<0 && err!=NO_INIT) 464 doThrow(env, "java/lang/IllegalArgumentException", NULL); 465} 466 467static void Surface_setSize( 468 JNIEnv* env, jobject clazz, jint w, jint h) 469{ 470 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 471 if (surface == 0) return; 472 status_t err = surface->setSize(w, h); 473 if (err<0 && err!=NO_INIT) 474 doThrow(env, "java/lang/IllegalArgumentException", NULL); 475} 476 477static void Surface_hide( 478 JNIEnv* env, jobject clazz) 479{ 480 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 481 if (surface == 0) return; 482 status_t err = surface->hide(); 483 if (err<0 && err!=NO_INIT) 484 doThrow(env, "java/lang/IllegalArgumentException", NULL); 485} 486 487static void Surface_show( 488 JNIEnv* env, jobject clazz) 489{ 490 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 491 if (surface == 0) return; 492 status_t err = surface->show(); 493 if (err<0 && err!=NO_INIT) 494 doThrow(env, "java/lang/IllegalArgumentException", NULL); 495} 496 497static void Surface_freeze( 498 JNIEnv* env, jobject clazz) 499{ 500 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 501 if (surface == 0) return; 502 status_t err = surface->freeze(); 503 if (err<0 && err!=NO_INIT) 504 doThrow(env, "java/lang/IllegalArgumentException", NULL); 505} 506 507static void Surface_unfreeze( 508 JNIEnv* env, jobject clazz) 509{ 510 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 511 if (surface == 0) return; 512 status_t err = surface->unfreeze(); 513 if (err<0 && err!=NO_INIT) 514 doThrow(env, "java/lang/IllegalArgumentException", NULL); 515} 516 517static void Surface_setFlags( 518 JNIEnv* env, jobject clazz, jint flags, jint mask) 519{ 520 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 521 if (surface == 0) return; 522 status_t err = surface->setFlags(flags, mask); 523 if (err<0 && err!=NO_INIT) 524 doThrow(env, "java/lang/IllegalArgumentException", NULL); 525} 526 527static void Surface_setTransparentRegion( 528 JNIEnv* env, jobject clazz, jobject argRegion) 529{ 530 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 531 if (surface == 0) return; 532 SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region); 533 534 const SkIRect& b(nativeRegion->getBounds()); 535 Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); 536 if (nativeRegion->isComplex()) { 537 SkRegion::Iterator it(*nativeRegion); 538 while (!it.done()) { 539 const SkIRect& r(it.rect()); 540 reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); 541 it.next(); 542 } 543 } 544 545 status_t err = surface->setTransparentRegionHint(reg); 546 if (err<0 && err!=NO_INIT) 547 doThrow(env, "java/lang/IllegalArgumentException", NULL); 548} 549 550static void Surface_setAlpha( 551 JNIEnv* env, jobject clazz, jfloat alpha) 552{ 553 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 554 if (surface == 0) return; 555 status_t err = surface->setAlpha(alpha); 556 if (err<0 && err!=NO_INIT) 557 doThrow(env, "java/lang/IllegalArgumentException", NULL); 558} 559 560static void Surface_setMatrix( 561 JNIEnv* env, jobject clazz, 562 jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) 563{ 564 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 565 if (surface == 0) return; 566 status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy); 567 if (err<0 && err!=NO_INIT) 568 doThrow(env, "java/lang/IllegalArgumentException", NULL); 569} 570 571static void Surface_setFreezeTint( 572 JNIEnv* env, jobject clazz, 573 jint tint) 574{ 575 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 576 if (surface == 0) return; 577 status_t err = surface->setFreezeTint(tint); 578 if (err<0 && err!=NO_INIT) 579 doThrow(env, "java/lang/IllegalArgumentException", NULL); 580} 581 582// ---------------------------------------------------------------------------- 583 584static void Surface_copyFrom( 585 JNIEnv* env, jobject clazz, jobject other) 586{ 587 if (clazz == other) 588 return; 589 590 if (other == NULL) { 591 doThrow(env, "java/lang/NullPointerException", NULL); 592 return; 593 } 594 595 /* 596 * This is used by the WindowManagerService just after constructing 597 * a Surface and is necessary for returning the Surface reference to 598 * the caller. At this point, we should only have a SurfaceControl. 599 */ 600 601 const sp<SurfaceControl>& surface = getSurfaceControl(env, clazz); 602 const sp<SurfaceControl>& rhs = getSurfaceControl(env, other); 603 if (!SurfaceControl::isSameSurface(surface, rhs)) { 604 // we reassign the surface only if it's a different one 605 // otherwise we would loose our client-side state. 606 setSurfaceControl(env, clazz, rhs); 607 } 608} 609 610static void Surface_readFromParcel( 611 JNIEnv* env, jobject clazz, jobject argParcel) 612{ 613 Parcel* parcel = (Parcel*)env->GetIntField( argParcel, no.native_parcel); 614 if (parcel == NULL) { 615 doThrow(env, "java/lang/NullPointerException", NULL); 616 return; 617 } 618 619 const sp<Surface>& curr(getSurface(env, clazz)); 620 sp<Surface> sur(Surface::readFromParcel(*parcel, curr)); 621 setSurface(env, clazz, sur); 622} 623 624static void Surface_writeToParcel( 625 JNIEnv* env, jobject clazz, jobject argParcel, jint flags) 626{ 627 Parcel* parcel = (Parcel*)env->GetIntField( 628 argParcel, no.native_parcel); 629 630 if (parcel == NULL) { 631 doThrow(env, "java/lang/NullPointerException", NULL); 632 return; 633 } 634 635 const sp<SurfaceControl>& control(getSurfaceControl(env, clazz)); 636 SurfaceControl::writeSurfaceToParcel(control, parcel); 637 if (flags & PARCELABLE_WRITE_RETURN_VALUE) { 638 setSurfaceControl(env, clazz, 0); 639 } 640} 641 642// ---------------------------------------------------------------------------- 643// ---------------------------------------------------------------------------- 644// ---------------------------------------------------------------------------- 645 646const char* const kSurfaceSessionClassPathName = "android/view/SurfaceSession"; 647const char* const kSurfaceClassPathName = "android/view/Surface"; 648static void nativeClassInit(JNIEnv* env, jclass clazz); 649 650static JNINativeMethod gSurfaceSessionMethods[] = { 651 {"init", "()V", (void*)SurfaceSession_init }, 652 {"destroy", "()V", (void*)SurfaceSession_destroy }, 653 {"kill", "()V", (void*)SurfaceSession_kill }, 654}; 655 656static JNINativeMethod gSurfaceMethods[] = { 657 {"nativeClassInit", "()V", (void*)nativeClassInit }, 658 {"init", "(Landroid/view/SurfaceSession;ILjava/lang/String;IIIII)V", (void*)Surface_init }, 659 {"init", "(Landroid/os/Parcel;)V", (void*)Surface_initParcel }, 660 {"getIdentity", "()I", (void*)Surface_getIdentity }, 661 {"destroy", "()V", (void*)Surface_destroy }, 662 {"release", "()V", (void*)Surface_release }, 663 {"copyFrom", "(Landroid/view/Surface;)V", (void*)Surface_copyFrom }, 664 {"isValid", "()Z", (void*)Surface_isValid }, 665 {"lockCanvasNative", "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;", (void*)Surface_lockCanvas }, 666 {"unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvasAndPost }, 667 {"unlockCanvas", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas }, 668 {"openTransaction", "()V", (void*)Surface_openTransaction }, 669 {"closeTransaction", "()V", (void*)Surface_closeTransaction }, 670 {"setOrientation", "(III)V", (void*)Surface_setOrientation }, 671 {"freezeDisplay", "(I)V", (void*)Surface_freezeDisplay }, 672 {"unfreezeDisplay", "(I)V", (void*)Surface_unfreezeDisplay }, 673 {"setLayer", "(I)V", (void*)Surface_setLayer }, 674 {"setPosition", "(II)V",(void*)Surface_setPosition }, 675 {"setSize", "(II)V",(void*)Surface_setSize }, 676 {"hide", "()V", (void*)Surface_hide }, 677 {"show", "()V", (void*)Surface_show }, 678 {"freeze", "()V", (void*)Surface_freeze }, 679 {"unfreeze", "()V", (void*)Surface_unfreeze }, 680 {"setFlags", "(II)V",(void*)Surface_setFlags }, 681 {"setTransparentRegionHint","(Landroid/graphics/Region;)V", (void*)Surface_setTransparentRegion }, 682 {"setAlpha", "(F)V", (void*)Surface_setAlpha }, 683 {"setMatrix", "(FFFF)V", (void*)Surface_setMatrix }, 684 {"setFreezeTint", "(I)V", (void*)Surface_setFreezeTint }, 685 {"readFromParcel", "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel }, 686 {"writeToParcel", "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel }, 687}; 688 689void nativeClassInit(JNIEnv* env, jclass clazz) 690{ 691 so.surface = env->GetFieldID(clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I"); 692 so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I"); 693 so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I"); 694 so.canvas = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;"); 695 696 jclass surfaceSession = env->FindClass("android/view/SurfaceSession"); 697 sso.client = env->GetFieldID(surfaceSession, "mClient", "I"); 698 699 jclass canvas = env->FindClass("android/graphics/Canvas"); 700 no.native_canvas = env->GetFieldID(canvas, "mNativeCanvas", "I"); 701 co.surfaceFormat = env->GetFieldID(canvas, "mSurfaceFormat", "I"); 702 703 jclass region = env->FindClass("android/graphics/Region"); 704 no.native_region = env->GetFieldID(region, "mNativeRegion", "I"); 705 706 jclass parcel = env->FindClass("android/os/Parcel"); 707 no.native_parcel = env->GetFieldID(parcel, "mObject", "I"); 708 709 jclass rect = env->FindClass("android/graphics/Rect"); 710 ro.l = env->GetFieldID(rect, "left", "I"); 711 ro.t = env->GetFieldID(rect, "top", "I"); 712 ro.r = env->GetFieldID(rect, "right", "I"); 713 ro.b = env->GetFieldID(rect, "bottom", "I"); 714 715 jclass point = env->FindClass("android/graphics/Point"); 716 po.x = env->GetFieldID(point, "x", "I"); 717 po.y = env->GetFieldID(point, "y", "I"); 718} 719 720int register_android_view_Surface(JNIEnv* env) 721{ 722 int err; 723 err = AndroidRuntime::registerNativeMethods(env, kSurfaceSessionClassPathName, 724 gSurfaceSessionMethods, NELEM(gSurfaceSessionMethods)); 725 726 err |= AndroidRuntime::registerNativeMethods(env, kSurfaceClassPathName, 727 gSurfaceMethods, NELEM(gSurfaceMethods)); 728 return err; 729} 730 731}; 732 733