android_view_Surface.cpp revision d2835935d2df8be70d1b37d3ef3b2fe0155b3422
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, int minLayer, int maxLayer, bool allLayers) { 453 status_t res = (width > 0 && height > 0) 454 ? (allLayers 455 ? mScreenshot.update(width, height) 456 : mScreenshot.update(width, height, minLayer, maxLayer)) 457 : mScreenshot.update(); 458 if (res != NO_ERROR) { 459 return res; 460 } 461 462 return NO_ERROR; 463 } 464 465 uint32_t getWidth() const { 466 return mScreenshot.getWidth(); 467 } 468 469 uint32_t getHeight() const { 470 return mScreenshot.getHeight(); 471 } 472 473 uint32_t getStride() const { 474 return mScreenshot.getStride(); 475 } 476 477 uint32_t getFormat() const { 478 return mScreenshot.getFormat(); 479 } 480 481protected: 482 // overrides from SkPixelRef 483 virtual void* onLockPixels(SkColorTable** ct) { 484 *ct = fCTable; 485 return (void*)mScreenshot.getPixels(); 486 } 487 488 virtual void onUnlockPixels() { 489 } 490 491private: 492 ScreenshotClient mScreenshot; 493 SkColorTable* fCTable; 494 495 typedef SkPixelRef INHERITED; 496}; 497 498static jobject doScreenshot(JNIEnv* env, jobject clazz, jint width, jint height, 499 jint minLayer, jint maxLayer, bool allLayers) 500{ 501 ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL); 502 if (pixels->update(width, height, minLayer, maxLayer, allLayers) != NO_ERROR) { 503 delete pixels; 504 return 0; 505 } 506 507 uint32_t w = pixels->getWidth(); 508 uint32_t h = pixels->getHeight(); 509 uint32_t s = pixels->getStride(); 510 uint32_t f = pixels->getFormat(); 511 ssize_t bpr = s * android::bytesPerPixel(f); 512 513 SkBitmap* bitmap = new SkBitmap(); 514 bitmap->setConfig(convertPixelFormat(f), w, h, bpr); 515 if (f == PIXEL_FORMAT_RGBX_8888) { 516 bitmap->setIsOpaque(true); 517 } 518 519 if (w > 0 && h > 0) { 520 bitmap->setPixelRef(pixels)->unref(); 521 bitmap->lockPixels(); 522 } else { 523 // be safe with an empty bitmap. 524 delete pixels; 525 bitmap->setPixels(NULL); 526 } 527 528 return GraphicsJNI::createBitmap(env, bitmap, false, NULL); 529} 530 531static jobject Surface_screenshotAll(JNIEnv* env, jobject clazz, jint width, jint height) 532{ 533 return doScreenshot(env, clazz, width, height, 0, 0, true); 534} 535 536static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height, 537 jint minLayer, jint maxLayer, bool allLayers) 538{ 539 return doScreenshot(env, clazz, width, height, minLayer, maxLayer, false); 540} 541 542static void Surface_setLayer( 543 JNIEnv* env, jobject clazz, jint zorder) 544{ 545 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 546 if (surface == 0) return; 547 status_t err = surface->setLayer(zorder); 548 if (err<0 && err!=NO_INIT) 549 doThrow(env, "java/lang/IllegalArgumentException", NULL); 550} 551 552static void Surface_setPosition( 553 JNIEnv* env, jobject clazz, jint x, jint y) 554{ 555 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 556 if (surface == 0) return; 557 status_t err = surface->setPosition(x, y); 558 if (err<0 && err!=NO_INIT) 559 doThrow(env, "java/lang/IllegalArgumentException", NULL); 560} 561 562static void Surface_setSize( 563 JNIEnv* env, jobject clazz, jint w, jint h) 564{ 565 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 566 if (surface == 0) return; 567 status_t err = surface->setSize(w, h); 568 if (err<0 && err!=NO_INIT) 569 doThrow(env, "java/lang/IllegalArgumentException", NULL); 570} 571 572static void Surface_hide( 573 JNIEnv* env, jobject clazz) 574{ 575 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 576 if (surface == 0) return; 577 status_t err = surface->hide(); 578 if (err<0 && err!=NO_INIT) 579 doThrow(env, "java/lang/IllegalArgumentException", NULL); 580} 581 582static void Surface_show( 583 JNIEnv* env, jobject clazz) 584{ 585 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 586 if (surface == 0) return; 587 status_t err = surface->show(); 588 if (err<0 && err!=NO_INIT) 589 doThrow(env, "java/lang/IllegalArgumentException", NULL); 590} 591 592static void Surface_freeze( 593 JNIEnv* env, jobject clazz) 594{ 595 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 596 if (surface == 0) return; 597 status_t err = surface->freeze(); 598 if (err<0 && err!=NO_INIT) 599 doThrow(env, "java/lang/IllegalArgumentException", NULL); 600} 601 602static void Surface_unfreeze( 603 JNIEnv* env, jobject clazz) 604{ 605 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 606 if (surface == 0) return; 607 status_t err = surface->unfreeze(); 608 if (err<0 && err!=NO_INIT) 609 doThrow(env, "java/lang/IllegalArgumentException", NULL); 610} 611 612static void Surface_setFlags( 613 JNIEnv* env, jobject clazz, jint flags, jint mask) 614{ 615 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 616 if (surface == 0) return; 617 status_t err = surface->setFlags(flags, mask); 618 if (err<0 && err!=NO_INIT) 619 doThrow(env, "java/lang/IllegalArgumentException", NULL); 620} 621 622static void Surface_setTransparentRegion( 623 JNIEnv* env, jobject clazz, jobject argRegion) 624{ 625 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 626 if (surface == 0) return; 627 SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region); 628 629 const SkIRect& b(nativeRegion->getBounds()); 630 Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); 631 if (nativeRegion->isComplex()) { 632 SkRegion::Iterator it(*nativeRegion); 633 while (!it.done()) { 634 const SkIRect& r(it.rect()); 635 reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); 636 it.next(); 637 } 638 } 639 640 status_t err = surface->setTransparentRegionHint(reg); 641 if (err<0 && err!=NO_INIT) 642 doThrow(env, "java/lang/IllegalArgumentException", NULL); 643} 644 645static void Surface_setAlpha( 646 JNIEnv* env, jobject clazz, jfloat alpha) 647{ 648 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 649 if (surface == 0) return; 650 status_t err = surface->setAlpha(alpha); 651 if (err<0 && err!=NO_INIT) 652 doThrow(env, "java/lang/IllegalArgumentException", NULL); 653} 654 655static void Surface_setMatrix( 656 JNIEnv* env, jobject clazz, 657 jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) 658{ 659 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 660 if (surface == 0) return; 661 status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy); 662 if (err<0 && err!=NO_INIT) 663 doThrow(env, "java/lang/IllegalArgumentException", NULL); 664} 665 666static void Surface_setFreezeTint( 667 JNIEnv* env, jobject clazz, 668 jint tint) 669{ 670 const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); 671 if (surface == 0) return; 672 status_t err = surface->setFreezeTint(tint); 673 if (err<0 && err!=NO_INIT) 674 doThrow(env, "java/lang/IllegalArgumentException", NULL); 675} 676 677// ---------------------------------------------------------------------------- 678 679static void Surface_copyFrom( 680 JNIEnv* env, jobject clazz, jobject other) 681{ 682 if (clazz == other) 683 return; 684 685 if (other == NULL) { 686 doThrow(env, "java/lang/NullPointerException", NULL); 687 return; 688 } 689 690 /* 691 * This is used by the WindowManagerService just after constructing 692 * a Surface and is necessary for returning the Surface reference to 693 * the caller. At this point, we should only have a SurfaceControl. 694 */ 695 696 const sp<SurfaceControl>& surface = getSurfaceControl(env, clazz); 697 const sp<SurfaceControl>& rhs = getSurfaceControl(env, other); 698 if (!SurfaceControl::isSameSurface(surface, rhs)) { 699 // we reassign the surface only if it's a different one 700 // otherwise we would loose our client-side state. 701 setSurfaceControl(env, clazz, rhs); 702 } 703} 704 705static void Surface_readFromParcel( 706 JNIEnv* env, jobject clazz, jobject argParcel) 707{ 708 Parcel* parcel = (Parcel*)env->GetIntField( argParcel, no.native_parcel); 709 if (parcel == NULL) { 710 doThrow(env, "java/lang/NullPointerException", NULL); 711 return; 712 } 713 714 sp<Surface> sur(Surface::readFromParcel(*parcel)); 715 setSurface(env, clazz, sur); 716} 717 718static void Surface_writeToParcel( 719 JNIEnv* env, jobject clazz, jobject argParcel, jint flags) 720{ 721 Parcel* parcel = (Parcel*)env->GetIntField( 722 argParcel, no.native_parcel); 723 724 if (parcel == NULL) { 725 doThrow(env, "java/lang/NullPointerException", NULL); 726 return; 727 } 728 729 const sp<SurfaceControl>& control(getSurfaceControl(env, clazz)); 730 SurfaceControl::writeSurfaceToParcel(control, parcel); 731 if (flags & PARCELABLE_WRITE_RETURN_VALUE) { 732 setSurfaceControl(env, clazz, 0); 733 } 734} 735 736// ---------------------------------------------------------------------------- 737// ---------------------------------------------------------------------------- 738// ---------------------------------------------------------------------------- 739 740const char* const kSurfaceSessionClassPathName = "android/view/SurfaceSession"; 741const char* const kSurfaceClassPathName = "android/view/Surface"; 742static void nativeClassInit(JNIEnv* env, jclass clazz); 743 744static JNINativeMethod gSurfaceSessionMethods[] = { 745 {"init", "()V", (void*)SurfaceSession_init }, 746 {"destroy", "()V", (void*)SurfaceSession_destroy }, 747 {"kill", "()V", (void*)SurfaceSession_kill }, 748}; 749 750static JNINativeMethod gSurfaceMethods[] = { 751 {"nativeClassInit", "()V", (void*)nativeClassInit }, 752 {"init", "(Landroid/view/SurfaceSession;ILjava/lang/String;IIIII)V", (void*)Surface_init }, 753 {"init", "(Landroid/os/Parcel;)V", (void*)Surface_initParcel }, 754 {"getIdentity", "()I", (void*)Surface_getIdentity }, 755 {"destroy", "()V", (void*)Surface_destroy }, 756 {"release", "()V", (void*)Surface_release }, 757 {"copyFrom", "(Landroid/view/Surface;)V", (void*)Surface_copyFrom }, 758 {"isValid", "()Z", (void*)Surface_isValid }, 759 {"lockCanvasNative", "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;", (void*)Surface_lockCanvas }, 760 {"unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvasAndPost }, 761 {"unlockCanvas", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas }, 762 {"openTransaction", "()V", (void*)Surface_openTransaction }, 763 {"closeTransaction", "()V", (void*)Surface_closeTransaction }, 764 {"setOrientation", "(III)V", (void*)Surface_setOrientation }, 765 {"freezeDisplay", "(I)V", (void*)Surface_freezeDisplay }, 766 {"unfreezeDisplay", "(I)V", (void*)Surface_unfreezeDisplay }, 767 {"screenshot", "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll }, 768 {"screenshot", "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot }, 769 {"setLayer", "(I)V", (void*)Surface_setLayer }, 770 {"setPosition", "(II)V",(void*)Surface_setPosition }, 771 {"setSize", "(II)V",(void*)Surface_setSize }, 772 {"hide", "()V", (void*)Surface_hide }, 773 {"show", "()V", (void*)Surface_show }, 774 {"freeze", "()V", (void*)Surface_freeze }, 775 {"unfreeze", "()V", (void*)Surface_unfreeze }, 776 {"setFlags", "(II)V",(void*)Surface_setFlags }, 777 {"setTransparentRegionHint","(Landroid/graphics/Region;)V", (void*)Surface_setTransparentRegion }, 778 {"setAlpha", "(F)V", (void*)Surface_setAlpha }, 779 {"setMatrix", "(FFFF)V", (void*)Surface_setMatrix }, 780 {"setFreezeTint", "(I)V", (void*)Surface_setFreezeTint }, 781 {"readFromParcel", "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel }, 782 {"writeToParcel", "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel }, 783}; 784 785void nativeClassInit(JNIEnv* env, jclass clazz) 786{ 787 so.surface = env->GetFieldID(clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I"); 788 so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I"); 789 so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I"); 790 so.canvas = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;"); 791 792 jclass surfaceSession = env->FindClass("android/view/SurfaceSession"); 793 sso.client = env->GetFieldID(surfaceSession, "mClient", "I"); 794 795 jclass canvas = env->FindClass("android/graphics/Canvas"); 796 no.native_canvas = env->GetFieldID(canvas, "mNativeCanvas", "I"); 797 co.surfaceFormat = env->GetFieldID(canvas, "mSurfaceFormat", "I"); 798 799 jclass region = env->FindClass("android/graphics/Region"); 800 no.native_region = env->GetFieldID(region, "mNativeRegion", "I"); 801 802 jclass parcel = env->FindClass("android/os/Parcel"); 803 no.native_parcel = env->GetFieldID(parcel, "mObject", "I"); 804 805 jclass rect = env->FindClass("android/graphics/Rect"); 806 ro.l = env->GetFieldID(rect, "left", "I"); 807 ro.t = env->GetFieldID(rect, "top", "I"); 808 ro.r = env->GetFieldID(rect, "right", "I"); 809 ro.b = env->GetFieldID(rect, "bottom", "I"); 810 811 jclass point = env->FindClass("android/graphics/Point"); 812 po.x = env->GetFieldID(point, "x", "I"); 813 po.y = env->GetFieldID(point, "y", "I"); 814} 815 816int register_android_view_Surface(JNIEnv* env) 817{ 818 int err; 819 err = AndroidRuntime::registerNativeMethods(env, kSurfaceSessionClassPathName, 820 gSurfaceSessionMethods, NELEM(gSurfaceSessionMethods)); 821 822 err |= AndroidRuntime::registerNativeMethods(env, kSurfaceClassPathName, 823 gSurfaceMethods, NELEM(gSurfaceMethods)); 824 return err; 825} 826 827}; 828