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