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