surface_texture.cc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/gl/android/surface_texture.h"
  5. #include <android/native_window_jni.h>
  6. #include <utility>
  7. #include "base/android/jni_android.h"
  8. #include "base/check.h"
  9. #include "base/debug/crash_logging.h"
  10. #include "ui/gl/android/scoped_java_surface.h"
  11. #include "ui/gl/android/surface_texture_listener.h"
  12. #include "ui/gl/gl_bindings.h"
  13. #include "ui/gl/gl_jni_headers/SurfaceTexturePlatformWrapper_jni.h"
  14. #ifndef GL_ANGLE_texture_storage_external
  15. #define GL_ANGLE_texture_storage_external 1
  16. #define GL_TEXTURE_NATIVE_ID_ANGLE 0x3481
  17. #endif /* GL_ANGLE_texture_storage_external */
  18. namespace gl {
  19. scoped_refptr<SurfaceTexture> SurfaceTexture::Create(int texture_id) {
  20. int native_id = texture_id;
  21. // ANGLE emulates texture IDs so query the native ID of the texture.
  22. if (texture_id != 0 &&
  23. gl::g_current_gl_driver->ext.b_GL_ANGLE_texture_external_update) {
  24. GLint prev_texture = 0;
  25. glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &prev_texture);
  26. glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
  27. glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_NATIVE_ID_ANGLE,
  28. &native_id);
  29. glBindTexture(GL_TEXTURE_EXTERNAL_OES, prev_texture);
  30. }
  31. JNIEnv* env = base::android::AttachCurrentThread();
  32. return new SurfaceTexture(
  33. Java_SurfaceTexturePlatformWrapper_create(env, native_id));
  34. }
  35. SurfaceTexture::SurfaceTexture(
  36. const base::android::ScopedJavaLocalRef<jobject>& j_surface_texture) {
  37. j_surface_texture_.Reset(j_surface_texture);
  38. }
  39. SurfaceTexture::~SurfaceTexture() {
  40. JNIEnv* env = base::android::AttachCurrentThread();
  41. Java_SurfaceTexturePlatformWrapper_destroy(env, j_surface_texture_);
  42. }
  43. void SurfaceTexture::SetFrameAvailableCallback(
  44. base::RepeatingClosure callback) {
  45. JNIEnv* env = base::android::AttachCurrentThread();
  46. Java_SurfaceTexturePlatformWrapper_setFrameAvailableCallback(
  47. env, j_surface_texture_,
  48. reinterpret_cast<intptr_t>(
  49. new SurfaceTextureListener(std::move(callback), false)));
  50. }
  51. void SurfaceTexture::SetFrameAvailableCallbackOnAnyThread(
  52. base::RepeatingClosure callback) {
  53. JNIEnv* env = base::android::AttachCurrentThread();
  54. Java_SurfaceTexturePlatformWrapper_setFrameAvailableCallback(
  55. env, j_surface_texture_,
  56. reinterpret_cast<intptr_t>(
  57. new SurfaceTextureListener(std::move(callback), true)));
  58. }
  59. void SurfaceTexture::UpdateTexImage() {
  60. static auto* kCrashKey = base::debug::AllocateCrashKeyString(
  61. "inside_surface_texture_update_tex_image",
  62. base::debug::CrashKeySize::Size256);
  63. base::debug::ScopedCrashKeyString scoped_crash_key(kCrashKey, "1");
  64. JNIEnv* env = base::android::AttachCurrentThread();
  65. Java_SurfaceTexturePlatformWrapper_updateTexImage(env, j_surface_texture_);
  66. // Notify ANGLE that the External texture binding has changed
  67. if (gl::g_current_gl_driver->ext.b_GL_ANGLE_texture_external_update)
  68. glInvalidateTextureANGLE(GL_TEXTURE_EXTERNAL_OES);
  69. }
  70. void SurfaceTexture::GetTransformMatrix(float mtx[16]) {
  71. JNIEnv* env = base::android::AttachCurrentThread();
  72. base::android::ScopedJavaLocalRef<jfloatArray> jmatrix(
  73. env, env->NewFloatArray(16));
  74. Java_SurfaceTexturePlatformWrapper_getTransformMatrix(env, j_surface_texture_,
  75. jmatrix);
  76. jfloat* elements = env->GetFloatArrayElements(jmatrix.obj(), nullptr);
  77. for (int i = 0; i < 16; ++i) {
  78. mtx[i] = static_cast<float>(elements[i]);
  79. }
  80. env->ReleaseFloatArrayElements(jmatrix.obj(), elements, JNI_ABORT);
  81. }
  82. void SurfaceTexture::AttachToGLContext() {
  83. // ANGLE emulates texture IDs so query the native ID of the texture.
  84. int texture_id = 0;
  85. if (gl::g_current_gl_driver->ext.b_GL_ANGLE_texture_external_update) {
  86. glGetTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_NATIVE_ID_ANGLE,
  87. &texture_id);
  88. } else {
  89. glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id);
  90. }
  91. DCHECK(texture_id);
  92. JNIEnv* env = base::android::AttachCurrentThread();
  93. Java_SurfaceTexturePlatformWrapper_attachToGLContext(env, j_surface_texture_,
  94. texture_id);
  95. // Notify ANGLE that the External texture binding has changed
  96. if (gl::g_current_gl_driver->ext.b_GL_ANGLE_texture_external_update) {
  97. glInvalidateTextureANGLE(GL_TEXTURE_EXTERNAL_OES);
  98. }
  99. }
  100. void SurfaceTexture::DetachFromGLContext() {
  101. JNIEnv* env = base::android::AttachCurrentThread();
  102. Java_SurfaceTexturePlatformWrapper_detachFromGLContext(env,
  103. j_surface_texture_);
  104. }
  105. ANativeWindow* SurfaceTexture::CreateSurface() {
  106. JNIEnv* env = base::android::AttachCurrentThread();
  107. ScopedJavaSurface surface(this);
  108. // Note: This ensures that any local references used by
  109. // ANativeWindow_fromSurface are released immediately. This is needed as a
  110. // workaround for https://code.google.com/p/android/issues/detail?id=68174
  111. base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env);
  112. ANativeWindow* native_window =
  113. ANativeWindow_fromSurface(env, surface.j_surface().obj());
  114. return native_window;
  115. }
  116. void SurfaceTexture::ReleaseBackBuffers() {
  117. JNIEnv* env = base::android::AttachCurrentThread();
  118. Java_SurfaceTexturePlatformWrapper_release(env, j_surface_texture_);
  119. }
  120. void SurfaceTexture::SetDefaultBufferSize(int width, int height) {
  121. JNIEnv* env = base::android::AttachCurrentThread();
  122. Java_SurfaceTexturePlatformWrapper_setDefaultBufferSize(
  123. env, j_surface_texture_, width, height);
  124. }
  125. } // namespace gl