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