Move SurfaceTexture implementation to libnativedisplay
Move SurfaceTexture C++ implementation from libgui to
libnativedisplay. Move ASurfaceTexture JNI implementation from
libandroid to libnativedisplay.
Move surface_texture_platform.h implementation in the same file
as ASurfaceTexture NDK implementation. Delete
ASurfaceTexture_create, which is no longer used by TextureLayer.
Move ASurfaceTexture definition from surface_texture_platform.h
to private implementation.
Test: pass CtsUiRenderingTestCases and CtsViewTestCases
Bug: 147060713
Change-Id: I9619124b8ab682c75efb5db17685b074ad422722
diff --git a/libs/nativedisplay/surfacetexture/surface_texture.cpp b/libs/nativedisplay/surfacetexture/surface_texture.cpp
new file mode 100644
index 0000000..1670fbb
--- /dev/null
+++ b/libs/nativedisplay/surfacetexture/surface_texture.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/surface_texture.h>
+#include <android/surface_texture_jni.h>
+
+#define LOG_TAG "ASurfaceTexture"
+
+#include <utils/Log.h>
+
+#include <gui/Surface.h>
+
+#include <surfacetexture/surface_texture_platform.h>
+#include <surfacetexture/SurfaceTexture.h>
+
+#include <mutex>
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+struct ASurfaceTexture {
+ android::sp<android::SurfaceTexture> consumer;
+ android::sp<android::IGraphicBufferProducer> producer;
+};
+
+using namespace android;
+
+const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
+
+struct fields_t {
+ jfieldID surfaceTexture;
+ jfieldID producer;
+};
+static fields_t fields;
+static std::once_flag sInitFieldsOnce;
+
+#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
+#define ANDROID_GRAPHICS_PRODUCER_JNI_ID "mProducer"
+
+static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
+{
+ fields.surfaceTexture = env->GetFieldID(clazz,
+ ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "J");
+ if (fields.surfaceTexture == NULL) {
+ ALOGE("can't find android/graphics/SurfaceTexture.%s",
+ ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
+ }
+ fields.producer = env->GetFieldID(clazz,
+ ANDROID_GRAPHICS_PRODUCER_JNI_ID, "J");
+ if (fields.producer == NULL) {
+ ALOGE("can't find android/graphics/SurfaceTexture.%s",
+ ANDROID_GRAPHICS_PRODUCER_JNI_ID);
+ }
+}
+
+static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
+ jclass clazz = env->FindClass(class_name);
+ LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
+ return clazz;
+}
+
+static void register_android_graphics_SurfaceTexture(JNIEnv* env)
+{
+ // Cache some fields.
+ ScopedLocalRef<jclass> klass(env, FindClassOrDie(env, kSurfaceTextureClassPathName));
+ SurfaceTexture_classInit(env, klass.get());
+}
+
+static bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) {
+ std::call_once(sInitFieldsOnce, [=]() {
+ register_android_graphics_SurfaceTexture(env);
+ });
+
+ jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
+ return env->IsInstanceOf(thiz, surfaceTextureClass);
+}
+
+static sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) {
+ std::call_once(sInitFieldsOnce, [=]() {
+ register_android_graphics_SurfaceTexture(env);
+ });
+
+ return (SurfaceTexture*)env->GetLongField(thiz, fields.surfaceTexture);
+}
+
+static sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) {
+ std::call_once(sInitFieldsOnce, [=]() {
+ register_android_graphics_SurfaceTexture(env);
+ });
+
+ return (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
+}
+
+// The following functions implement NDK API.
+ASurfaceTexture* ASurfaceTexture_fromSurfaceTexture(JNIEnv* env, jobject surfacetexture) {
+ if (!surfacetexture || !android_SurfaceTexture_isInstanceOf(env, surfacetexture)) {
+ return nullptr;
+ }
+ ASurfaceTexture* ast = new ASurfaceTexture;
+ ast->consumer = SurfaceTexture_getSurfaceTexture(env, surfacetexture);
+ ast->producer = SurfaceTexture_getProducer(env, surfacetexture);
+ return ast;
+}
+
+ANativeWindow* ASurfaceTexture_acquireANativeWindow(ASurfaceTexture* st) {
+ sp<Surface> surface = new Surface(st->producer);
+ ANativeWindow* win(surface.get());
+ ANativeWindow_acquire(win);
+ return win;
+}
+
+void ASurfaceTexture_release(ASurfaceTexture* st) {
+ delete st;
+}
+
+int ASurfaceTexture_attachToGLContext(ASurfaceTexture* st, uint32_t tex) {
+ return st->consumer->attachToContext(tex);
+}
+
+int ASurfaceTexture_detachFromGLContext(ASurfaceTexture* st) {
+ return st->consumer->detachFromContext();
+}
+
+int ASurfaceTexture_updateTexImage(ASurfaceTexture* st) {
+ return st->consumer->updateTexImage();
+}
+
+void ASurfaceTexture_getTransformMatrix(ASurfaceTexture* st, float mtx[16]) {
+ st->consumer->getTransformMatrix(mtx);
+}
+
+int64_t ASurfaceTexture_getTimestamp(ASurfaceTexture* st) {
+ return st->consumer->getTimestamp();
+}
+
+// The following functions are private/unstable API.
+namespace android {
+
+unsigned int ASurfaceTexture_getCurrentTextureTarget(ASurfaceTexture* st) {
+ return st->consumer->getCurrentTextureTarget();
+}
+
+void ASurfaceTexture_takeConsumerOwnership(ASurfaceTexture* texture) {
+ texture->consumer->takeConsumerOwnership();
+}
+
+void ASurfaceTexture_releaseConsumerOwnership(ASurfaceTexture* texture) {
+ texture->consumer->releaseConsumerOwnership();
+}
+
+AHardwareBuffer* ASurfaceTexture_dequeueBuffer(ASurfaceTexture* st, int* outSlotid,
+ android_dataspace* outDataspace,
+ float* outTransformMatrix, bool* outNewContent,
+ ASurfaceTexture_createReleaseFence createFence,
+ ASurfaceTexture_fenceWait fenceWait, void* handle) {
+ sp<GraphicBuffer> buffer;
+ *outNewContent = false;
+ bool queueEmpty;
+ do {
+ buffer = st->consumer->dequeueBuffer(outSlotid, outDataspace, outTransformMatrix,
+ &queueEmpty, createFence, fenceWait, handle);
+ if (!queueEmpty) {
+ *outNewContent = true;
+ }
+ } while (buffer.get() && (!queueEmpty));
+ return reinterpret_cast<AHardwareBuffer*>(buffer.get());
+}
+
+} // namespace android