android_view_SurfaceControl.cpp revision 550780745fa28ae9a87d02331841ca5ce4f9c763
1/* 2 * Copyright (C) 2013 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 "SurfaceControl" 18 19#include "android_os_Parcel.h" 20#include "android_util_Binder.h" 21#include "android/graphics/Bitmap.h" 22#include "android/graphics/GraphicsJNI.h" 23#include "android/graphics/Region.h" 24#include "core_jni_helpers.h" 25 26#include <JNIHelp.h> 27#include <ScopedUtfChars.h> 28#include <android_runtime/android_view_Surface.h> 29#include <android_runtime/android_view_SurfaceSession.h> 30#include <gui/Surface.h> 31#include <gui/SurfaceComposerClient.h> 32#include <jni.h> 33#include <memory> 34#include <stdio.h> 35#include <ui/DisplayInfo.h> 36#include <ui/FrameStats.h> 37#include <ui/Rect.h> 38#include <ui/Region.h> 39#include <utils/Log.h> 40 41// ---------------------------------------------------------------------------- 42 43namespace android { 44 45static const char* const OutOfResourcesException = 46 "android/view/Surface$OutOfResourcesException"; 47 48static struct { 49 jclass clazz; 50 jmethodID ctor; 51 jfieldID width; 52 jfieldID height; 53 jfieldID refreshRate; 54 jfieldID density; 55 jfieldID xDpi; 56 jfieldID yDpi; 57 jfieldID secure; 58 jfieldID appVsyncOffsetNanos; 59 jfieldID presentationDeadlineNanos; 60 jfieldID colorTransform; 61} gPhysicalDisplayInfoClassInfo; 62 63static struct { 64 jfieldID bottom; 65 jfieldID left; 66 jfieldID right; 67 jfieldID top; 68} gRectClassInfo; 69 70// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref. 71void DeleteScreenshot(void* addr, void* context) { 72 SkASSERT(addr == ((ScreenshotClient*) context)->getPixels()); 73 delete ((ScreenshotClient*) context); 74} 75 76static struct { 77 nsecs_t UNDEFINED_TIME_NANO; 78 jmethodID init; 79} gWindowContentFrameStatsClassInfo; 80 81static struct { 82 nsecs_t UNDEFINED_TIME_NANO; 83 jmethodID init; 84} gWindowAnimationFrameStatsClassInfo; 85 86// ---------------------------------------------------------------------------- 87 88static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj, 89 jstring nameStr, jint w, jint h, jint format, jint flags) { 90 ScopedUtfChars name(env, nameStr); 91 sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj)); 92 sp<SurfaceControl> surface = client->createSurface( 93 String8(name.c_str()), w, h, format, flags); 94 if (surface == NULL) { 95 jniThrowException(env, OutOfResourcesException, NULL); 96 return 0; 97 } 98 surface->incStrong((void *)nativeCreate); 99 return reinterpret_cast<jlong>(surface.get()); 100} 101 102static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) { 103 sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject)); 104 ctrl->decStrong((void *)nativeCreate); 105} 106 107static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { 108 sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject)); 109 ctrl->clear(); 110 ctrl->decStrong((void *)nativeCreate); 111} 112 113static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, 114 jobject displayTokenObj, jobject sourceCropObj, jint width, jint height, 115 jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform, 116 int rotation) { 117 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); 118 if (displayToken == NULL) { 119 return NULL; 120 } 121 122 int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); 123 int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); 124 int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); 125 int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); 126 Rect sourceCrop(left, top, right, bottom); 127 128 std::unique_ptr<ScreenshotClient> screenshot(new ScreenshotClient()); 129 status_t res; 130 if (allLayers) { 131 minLayer = 0; 132 maxLayer = -1; 133 } 134 135 res = screenshot->update(displayToken, sourceCrop, width, height, 136 minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation)); 137 if (res != NO_ERROR) { 138 return NULL; 139 } 140 141 SkColorType ct; 142 SkAlphaType at; 143 switch (screenshot->getFormat()) { 144 case PIXEL_FORMAT_RGBX_8888: { 145 ct = kRGBA_8888_SkColorType; 146 at = kOpaque_SkAlphaType; 147 break; 148 } 149 case PIXEL_FORMAT_RGBA_8888: { 150 ct = kRGBA_8888_SkColorType; 151 at = kPremul_SkAlphaType; 152 break; 153 } 154 case PIXEL_FORMAT_RGB_565: { 155 ct = kRGB_565_SkColorType; 156 at = kOpaque_SkAlphaType; 157 break; 158 } 159 default: { 160 return NULL; 161 } 162 } 163 SkImageInfo screenshotInfo = SkImageInfo::Make(screenshot->getWidth(), 164 screenshot->getHeight(), 165 ct, at); 166 167 const size_t rowBytes = 168 screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat()); 169 170 if (!screenshotInfo.width() || !screenshotInfo.height()) { 171 return NULL; 172 } 173 174 Bitmap* bitmap = new Bitmap( 175 (void*) screenshot->getPixels(), (void*) screenshot.get(), DeleteScreenshot, 176 screenshotInfo, rowBytes, nullptr); 177 screenshot.release(); 178 bitmap->peekAtPixelRef()->setImmutable(); 179 180 return GraphicsJNI::createBitmap(env, bitmap, 181 GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL); 182} 183 184static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, 185 jobject surfaceObj, jobject sourceCropObj, jint width, jint height, 186 jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { 187 sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); 188 if (displayToken != NULL) { 189 sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); 190 if (consumer != NULL) { 191 int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); 192 int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); 193 int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); 194 int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); 195 Rect sourceCrop(left, top, right, bottom); 196 197 if (allLayers) { 198 minLayer = 0; 199 maxLayer = -1; 200 } 201 ScreenshotClient::capture(displayToken, 202 consumer->getIGraphicBufferProducer(), sourceCrop, 203 width, height, uint32_t(minLayer), uint32_t(maxLayer), 204 useIdentityTransform); 205 } 206 } 207} 208 209static void nativeOpenTransaction(JNIEnv* env, jclass clazz) { 210 SurfaceComposerClient::openGlobalTransaction(); 211} 212 213static void nativeCloseTransaction(JNIEnv* env, jclass clazz) { 214 SurfaceComposerClient::closeGlobalTransaction(); 215} 216 217static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) { 218 SurfaceComposerClient::setAnimationTransaction(); 219} 220 221static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong nativeObject, jint zorder) { 222 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 223 status_t err = ctrl->setLayer(zorder); 224 if (err < 0 && err != NO_INIT) { 225 doThrowIAE(env); 226 } 227} 228 229static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat x, jfloat y) { 230 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 231 status_t err = ctrl->setPosition(x, y); 232 if (err < 0 && err != NO_INIT) { 233 doThrowIAE(env); 234 } 235} 236 237static void nativeSetSize(JNIEnv* env, jclass clazz, jlong nativeObject, jint w, jint h) { 238 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 239 status_t err = ctrl->setSize(w, h); 240 if (err < 0 && err != NO_INIT) { 241 doThrowIAE(env); 242 } 243} 244 245static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong nativeObject, jint flags, jint mask) { 246 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 247 status_t err = ctrl->setFlags(flags, mask); 248 if (err < 0 && err != NO_INIT) { 249 doThrowIAE(env); 250 } 251} 252 253static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong nativeObject, jobject regionObj) { 254 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 255 SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj); 256 if (!region) { 257 doThrowIAE(env); 258 return; 259 } 260 261 const SkIRect& b(region->getBounds()); 262 Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); 263 if (region->isComplex()) { 264 SkRegion::Iterator it(*region); 265 while (!it.done()) { 266 const SkIRect& r(it.rect()); 267 reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); 268 it.next(); 269 } 270 } 271 272 status_t err = ctrl->setTransparentRegionHint(reg); 273 if (err < 0 && err != NO_INIT) { 274 doThrowIAE(env); 275 } 276} 277 278static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat alpha) { 279 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 280 status_t err = ctrl->setAlpha(alpha); 281 if (err < 0 && err != NO_INIT) { 282 doThrowIAE(env); 283 } 284} 285 286static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong nativeObject, 287 jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) { 288 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 289 status_t err = ctrl->setMatrix(dsdx, dtdx, dsdy, dtdy); 290 if (err < 0 && err != NO_INIT) { 291 doThrowIAE(env); 292 } 293} 294 295static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong nativeObject, 296 jint l, jint t, jint r, jint b) { 297 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 298 Rect crop(l, t, r, b); 299 status_t err = ctrl->setCrop(crop); 300 if (err < 0 && err != NO_INIT) { 301 doThrowIAE(env); 302 } 303} 304 305static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong nativeObject, jint layerStack) { 306 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 307 status_t err = ctrl->setLayerStack(layerStack); 308 if (err < 0 && err != NO_INIT) { 309 doThrowIAE(env); 310 } 311} 312 313static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) { 314 sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id)); 315 return javaObjectForIBinder(env, token); 316} 317 318static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj, 319 jboolean secure) { 320 ScopedUtfChars name(env, nameObj); 321 sp<IBinder> token(SurfaceComposerClient::createDisplay( 322 String8(name.c_str()), bool(secure))); 323 return javaObjectForIBinder(env, token); 324} 325 326static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { 327 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 328 if (token == NULL) return; 329 SurfaceComposerClient::destroyDisplay(token); 330} 331 332static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz, 333 jobject tokenObj, jlong nativeSurfaceObject) { 334 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 335 if (token == NULL) return; 336 sp<IGraphicBufferProducer> bufferProducer; 337 sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject)); 338 if (sur != NULL) { 339 bufferProducer = sur->getIGraphicBufferProducer(); 340 } 341 SurfaceComposerClient::setDisplaySurface(token, bufferProducer); 342} 343 344static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz, 345 jobject tokenObj, jint layerStack) { 346 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 347 if (token == NULL) return; 348 349 SurfaceComposerClient::setDisplayLayerStack(token, layerStack); 350} 351 352static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz, 353 jobject tokenObj, jint orientation, 354 jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom, 355 jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) { 356 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 357 if (token == NULL) return; 358 Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom); 359 Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom); 360 SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect); 361} 362 363static void nativeSetDisplaySize(JNIEnv* env, jclass clazz, 364 jobject tokenObj, jint width, jint height) { 365 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 366 if (token == NULL) return; 367 SurfaceComposerClient::setDisplaySize(token, width, height); 368} 369 370static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz, 371 jobject tokenObj) { 372 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 373 if (token == NULL) return NULL; 374 375 Vector<DisplayInfo> configs; 376 if (SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR || 377 configs.size() == 0) { 378 return NULL; 379 } 380 381 jobjectArray configArray = env->NewObjectArray(configs.size(), 382 gPhysicalDisplayInfoClassInfo.clazz, NULL); 383 384 for (size_t c = 0; c < configs.size(); ++c) { 385 const DisplayInfo& info = configs[c]; 386 jobject infoObj = env->NewObject(gPhysicalDisplayInfoClassInfo.clazz, 387 gPhysicalDisplayInfoClassInfo.ctor); 388 env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w); 389 env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h); 390 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps); 391 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density); 392 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi); 393 env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi); 394 env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure); 395 env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos, 396 info.appVsyncOffset); 397 env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos, 398 info.presentationDeadline); 399 env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.colorTransform, 400 info.colorTransform); 401 env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj); 402 env->DeleteLocalRef(infoObj); 403 } 404 405 return configArray; 406} 407 408static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) { 409 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 410 if (token == NULL) return -1; 411 return static_cast<jint>(SurfaceComposerClient::getActiveConfig(token)); 412} 413 414static jboolean nativeSetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj, jint id) { 415 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 416 if (token == NULL) return JNI_FALSE; 417 status_t err = SurfaceComposerClient::setActiveConfig(token, static_cast<int>(id)); 418 return err == NO_ERROR ? JNI_TRUE : JNI_FALSE; 419} 420 421static void nativeSetDisplayPowerMode(JNIEnv* env, jclass clazz, jobject tokenObj, jint mode) { 422 sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); 423 if (token == NULL) return; 424 425 ALOGD_IF_SLOW(100, "Excessive delay in setPowerMode()"); 426 SurfaceComposerClient::setDisplayPowerMode(token, mode); 427} 428 429static jboolean nativeClearContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject) { 430 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 431 status_t err = ctrl->clearLayerFrameStats(); 432 433 if (err < 0 && err != NO_INIT) { 434 doThrowIAE(env); 435 } 436 437 // The other end is not ready, just report we failed. 438 if (err == NO_INIT) { 439 return JNI_FALSE; 440 } 441 442 return JNI_TRUE; 443} 444 445static jboolean nativeGetContentFrameStats(JNIEnv* env, jclass clazz, jlong nativeObject, 446 jobject outStats) { 447 FrameStats stats; 448 449 SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); 450 status_t err = ctrl->getLayerFrameStats(&stats); 451 if (err < 0 && err != NO_INIT) { 452 doThrowIAE(env); 453 } 454 455 // The other end is not ready, fine just return empty stats. 456 if (err == NO_INIT) { 457 return JNI_FALSE; 458 } 459 460 jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano); 461 size_t frameCount = stats.desiredPresentTimesNano.size(); 462 463 jlongArray postedTimesNanoDst = env->NewLongArray(frameCount); 464 if (postedTimesNanoDst == NULL) { 465 return JNI_FALSE; 466 } 467 468 jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount); 469 if (presentedTimesNanoDst == NULL) { 470 return JNI_FALSE; 471 } 472 473 jlongArray readyTimesNanoDst = env->NewLongArray(frameCount); 474 if (readyTimesNanoDst == NULL) { 475 return JNI_FALSE; 476 } 477 478 nsecs_t postedTimesNanoSrc[frameCount]; 479 nsecs_t presentedTimesNanoSrc[frameCount]; 480 nsecs_t readyTimesNanoSrc[frameCount]; 481 482 for (size_t i = 0; i < frameCount; i++) { 483 nsecs_t postedTimeNano = stats.desiredPresentTimesNano[i]; 484 if (postedTimeNano == INT64_MAX) { 485 postedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO; 486 } 487 postedTimesNanoSrc[i] = postedTimeNano; 488 489 nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i]; 490 if (presentedTimeNano == INT64_MAX) { 491 presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO; 492 } 493 presentedTimesNanoSrc[i] = presentedTimeNano; 494 495 nsecs_t readyTimeNano = stats.frameReadyTimesNano[i]; 496 if (readyTimeNano == INT64_MAX) { 497 readyTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO; 498 } 499 readyTimesNanoSrc[i] = readyTimeNano; 500 } 501 502 env->SetLongArrayRegion(postedTimesNanoDst, 0, frameCount, postedTimesNanoSrc); 503 env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc); 504 env->SetLongArrayRegion(readyTimesNanoDst, 0, frameCount, readyTimesNanoSrc); 505 506 env->CallVoidMethod(outStats, gWindowContentFrameStatsClassInfo.init, refreshPeriodNano, 507 postedTimesNanoDst, presentedTimesNanoDst, readyTimesNanoDst); 508 509 if (env->ExceptionCheck()) { 510 return JNI_FALSE; 511 } 512 513 return JNI_TRUE; 514} 515 516static jboolean nativeClearAnimationFrameStats(JNIEnv* env, jclass clazz) { 517 status_t err = SurfaceComposerClient::clearAnimationFrameStats(); 518 519 if (err < 0 && err != NO_INIT) { 520 doThrowIAE(env); 521 } 522 523 // The other end is not ready, just report we failed. 524 if (err == NO_INIT) { 525 return JNI_FALSE; 526 } 527 528 return JNI_TRUE; 529} 530 531static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject outStats) { 532 FrameStats stats; 533 534 status_t err = SurfaceComposerClient::getAnimationFrameStats(&stats); 535 if (err < 0 && err != NO_INIT) { 536 doThrowIAE(env); 537 } 538 539 // The other end is not ready, fine just return empty stats. 540 if (err == NO_INIT) { 541 return JNI_FALSE; 542 } 543 544 jlong refreshPeriodNano = static_cast<jlong>(stats.refreshPeriodNano); 545 size_t frameCount = stats.desiredPresentTimesNano.size(); 546 547 jlongArray presentedTimesNanoDst = env->NewLongArray(frameCount); 548 if (presentedTimesNanoDst == NULL) { 549 return JNI_FALSE; 550 } 551 552 nsecs_t presentedTimesNanoSrc[frameCount]; 553 554 for (size_t i = 0; i < frameCount; i++) { 555 nsecs_t presentedTimeNano = stats.actualPresentTimesNano[i]; 556 if (presentedTimeNano == INT64_MAX) { 557 presentedTimeNano = gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO; 558 } 559 presentedTimesNanoSrc[i] = presentedTimeNano; 560 } 561 562 env->SetLongArrayRegion(presentedTimesNanoDst, 0, frameCount, presentedTimesNanoSrc); 563 564 env->CallVoidMethod(outStats, gWindowAnimationFrameStatsClassInfo.init, refreshPeriodNano, 565 presentedTimesNanoDst); 566 567 if (env->ExceptionCheck()) { 568 return JNI_FALSE; 569 } 570 571 return JNI_TRUE; 572} 573 574// ---------------------------------------------------------------------------- 575 576static const JNINativeMethod sSurfaceControlMethods[] = { 577 {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)J", 578 (void*)nativeCreate }, 579 {"nativeRelease", "(J)V", 580 (void*)nativeRelease }, 581 {"nativeDestroy", "(J)V", 582 (void*)nativeDestroy }, 583 {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;", 584 (void*)nativeScreenshotBitmap }, 585 {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V", 586 (void*)nativeScreenshot }, 587 {"nativeOpenTransaction", "()V", 588 (void*)nativeOpenTransaction }, 589 {"nativeCloseTransaction", "()V", 590 (void*)nativeCloseTransaction }, 591 {"nativeSetAnimationTransaction", "()V", 592 (void*)nativeSetAnimationTransaction }, 593 {"nativeSetLayer", "(JI)V", 594 (void*)nativeSetLayer }, 595 {"nativeSetPosition", "(JFF)V", 596 (void*)nativeSetPosition }, 597 {"nativeSetSize", "(JII)V", 598 (void*)nativeSetSize }, 599 {"nativeSetTransparentRegionHint", "(JLandroid/graphics/Region;)V", 600 (void*)nativeSetTransparentRegionHint }, 601 {"nativeSetAlpha", "(JF)V", 602 (void*)nativeSetAlpha }, 603 {"nativeSetMatrix", "(JFFFF)V", 604 (void*)nativeSetMatrix }, 605 {"nativeSetFlags", "(JII)V", 606 (void*)nativeSetFlags }, 607 {"nativeSetWindowCrop", "(JIIII)V", 608 (void*)nativeSetWindowCrop }, 609 {"nativeSetLayerStack", "(JI)V", 610 (void*)nativeSetLayerStack }, 611 {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;", 612 (void*)nativeGetBuiltInDisplay }, 613 {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;", 614 (void*)nativeCreateDisplay }, 615 {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V", 616 (void*)nativeDestroyDisplay }, 617 {"nativeSetDisplaySurface", "(Landroid/os/IBinder;J)V", 618 (void*)nativeSetDisplaySurface }, 619 {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V", 620 (void*)nativeSetDisplayLayerStack }, 621 {"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V", 622 (void*)nativeSetDisplayProjection }, 623 {"nativeSetDisplaySize", "(Landroid/os/IBinder;II)V", 624 (void*)nativeSetDisplaySize }, 625 {"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;", 626 (void*)nativeGetDisplayConfigs }, 627 {"nativeGetActiveConfig", "(Landroid/os/IBinder;)I", 628 (void*)nativeGetActiveConfig }, 629 {"nativeSetActiveConfig", "(Landroid/os/IBinder;I)Z", 630 (void*)nativeSetActiveConfig }, 631 {"nativeClearContentFrameStats", "(J)Z", 632 (void*)nativeClearContentFrameStats }, 633 {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z", 634 (void*)nativeGetContentFrameStats }, 635 {"nativeClearAnimationFrameStats", "()Z", 636 (void*)nativeClearAnimationFrameStats }, 637 {"nativeGetAnimationFrameStats", "(Landroid/view/WindowAnimationFrameStats;)Z", 638 (void*)nativeGetAnimationFrameStats }, 639 {"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V", 640 (void*)nativeSetDisplayPowerMode }, 641}; 642 643int register_android_view_SurfaceControl(JNIEnv* env) 644{ 645 int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl", 646 sSurfaceControlMethods, NELEM(sSurfaceControlMethods)); 647 648 jclass clazz = FindClassOrDie(env, "android/view/SurfaceControl$PhysicalDisplayInfo"); 649 gPhysicalDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); 650 gPhysicalDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, 651 gPhysicalDisplayInfoClassInfo.clazz, "<init>", "()V"); 652 gPhysicalDisplayInfoClassInfo.width = GetFieldIDOrDie(env, clazz, "width", "I"); 653 gPhysicalDisplayInfoClassInfo.height = GetFieldIDOrDie(env, clazz, "height", "I"); 654 gPhysicalDisplayInfoClassInfo.refreshRate = GetFieldIDOrDie(env, clazz, "refreshRate", "F"); 655 gPhysicalDisplayInfoClassInfo.density = GetFieldIDOrDie(env, clazz, "density", "F"); 656 gPhysicalDisplayInfoClassInfo.xDpi = GetFieldIDOrDie(env, clazz, "xDpi", "F"); 657 gPhysicalDisplayInfoClassInfo.yDpi = GetFieldIDOrDie(env, clazz, "yDpi", "F"); 658 gPhysicalDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, clazz, "secure", "Z"); 659 gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos = GetFieldIDOrDie(env, 660 clazz, "appVsyncOffsetNanos", "J"); 661 gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = GetFieldIDOrDie(env, 662 clazz, "presentationDeadlineNanos", "J"); 663 gPhysicalDisplayInfoClassInfo.colorTransform = GetFieldIDOrDie(env, clazz, 664 "colorTransform", "I"); 665 666 jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect"); 667 gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I"); 668 gRectClassInfo.left = GetFieldIDOrDie(env, rectClazz, "left", "I"); 669 gRectClassInfo.right = GetFieldIDOrDie(env, rectClazz, "right", "I"); 670 gRectClassInfo.top = GetFieldIDOrDie(env, rectClazz, "top", "I"); 671 672 jclass frameStatsClazz = FindClassOrDie(env, "android/view/FrameStats"); 673 jfieldID undefined_time_nano_field = GetStaticFieldIDOrDie(env, 674 frameStatsClazz, "UNDEFINED_TIME_NANO", "J"); 675 nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field); 676 677 jclass contFrameStatsClazz = FindClassOrDie(env, "android/view/WindowContentFrameStats"); 678 gWindowContentFrameStatsClassInfo.init = GetMethodIDOrDie(env, 679 contFrameStatsClazz, "init", "(J[J[J[J)V"); 680 gWindowContentFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano; 681 682 jclass animFrameStatsClazz = FindClassOrDie(env, "android/view/WindowAnimationFrameStats"); 683 gWindowAnimationFrameStatsClassInfo.init = GetMethodIDOrDie(env, 684 animFrameStatsClazz, "init", "(J[J)V"); 685 gWindowAnimationFrameStatsClassInfo.UNDEFINED_TIME_NANO = undefined_time_nano; 686 687 return err; 688} 689 690}; 691