diff options
3 files changed, 97 insertions, 14 deletions
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index 4b39092..79f4403 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -33,6 +33,7 @@ import android.util.Size; import android.view.Surface; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import static android.hardware.camera2.legacy.LegacyExceptionUtils.*; @@ -271,6 +272,9 @@ public class LegacyCameraDevice implements AutoCloseable { return BAD_VALUE; } + List<Long> surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() : + getSurfaceIds(mConfiguredSurfaces); + // Make sure that there all requests have at least 1 surface; all surfaces are non-null for (CaptureRequest request : requestList) { if (request.getTargets().isEmpty()) { @@ -287,7 +291,7 @@ public class LegacyCameraDevice implements AutoCloseable { Log.e(TAG, "submitRequestList - must configure " + " device with valid surfaces before submitting requests"); return INVALID_OPERATION; - } else if (!mConfiguredSurfaces.contains(surface)) { + } else if (!containsSurfaceId(surface, surfaceIds)) { Log.e(TAG, "submitRequestList - cannot use a surface that wasn't configured"); return BAD_VALUE; } @@ -430,6 +434,32 @@ public class LegacyCameraDevice implements AutoCloseable { LegacyExceptionUtils.throwOnError(nativeSetSurfaceDimens(surface, width, height)); } + static long getSurfaceId(Surface surface) { + checkNotNull(surface); + return nativeGetSurfaceId(surface); + } + + static List<Long> getSurfaceIds(Collection<Surface> surfaces) { + if (surfaces == null) { + throw new NullPointerException("Null argument surfaces"); + } + List<Long> surfaceIds = new ArrayList<>(); + for (Surface s : surfaces) { + long id = getSurfaceId(s); + if (id == 0) { + throw new IllegalStateException( + "Configured surface had null native GraphicBufferProducer pointer!"); + } + surfaceIds.add(id); + } + return surfaceIds; + } + + static boolean containsSurfaceId(Surface s, List<Long> ids) { + long id = getSurfaceId(s); + return ids.contains(id); + } + private static native int nativeDetectSurfaceType(Surface surface); private static native int nativeDetectSurfaceDimens(Surface surface, @@ -445,4 +475,5 @@ public class LegacyCameraDevice implements AutoCloseable { private static native int nativeSetSurfaceDimens(Surface surface, int width, int height); + private static native long nativeGetSurfaceId(Surface surface); } diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java index e38624a..9969fd2 100644 --- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java @@ -492,19 +492,20 @@ public class SurfaceTextureRenderer { && (mConversionSurfaces == null || mConversionSurfaces.size() == 0)) { return; } + checkGlError("before updateTexImage"); mSurfaceTexture.updateTexImage(); if (targetSurfaces == null) return; + List<Long> targetSurfaceIds = LegacyCameraDevice.getSurfaceIds(targetSurfaces); for (EGLSurfaceHolder holder : mSurfaces) { - if (targetSurfaces.contains(holder.surface)) { + if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) { makeCurrent(holder.eglSurface); drawFrame(mSurfaceTexture); swapBuffers(holder.eglSurface); } - } for (EGLSurfaceHolder holder : mConversionSurfaces) { - if (targetSurfaces.contains(holder.surface)) { + if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) { makeCurrent(holder.eglSurface); drawFrame(mSurfaceTexture); mPBufferPixels.clear(); diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp index 2f24a69..9621bb2 100644 --- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp @@ -25,10 +25,15 @@ #include "android_runtime/AndroidRuntime.h" #include "android_runtime/android_view_Surface.h" +#include <gui/Surface.h> +#include <gui/IGraphicBufferProducer.h> #include <ui/GraphicBuffer.h> #include <system/window.h> #include <hardware/camera3.h> +#include <stdint.h> +#include <inttypes.h> + using namespace android; // fully-qualified class name @@ -192,8 +197,8 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, switch(pixelFmt) { case HAL_PIXEL_FORMAT_YCrCb_420_SP: { if (bufSize < width * height * 4) { - ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__, - bufSize); + ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions", + __FUNCTION__, bufSize); return BAD_VALUE; } uint8_t* img = NULL; @@ -214,8 +219,8 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, } case HAL_PIXEL_FORMAT_YV12: { if (bufSize < width * height * 4) { - ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__, - bufSize); + ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions", + __FUNCTION__, bufSize); return BAD_VALUE; } @@ -251,8 +256,8 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, // Software writes with YCbCr_420_888 format are unsupported // by the gralloc module for now if (bufSize < width * height * 4) { - ALOGE("%s: PixelBuffer size %lld to small for given dimensions", __FUNCTION__, - bufSize); + ALOGE("%s: PixelBuffer size %" PRId32 " to small for given dimensions", + __FUNCTION__, bufSize); return BAD_VALUE; } android_ycbcr ycbcr = android_ycbcr(); @@ -269,7 +274,7 @@ static status_t produceFrame(const sp<ANativeWindow>& anw, } case HAL_PIXEL_FORMAT_BLOB: { if (bufSize != width || height != 1) { - ALOGE("%s: Incorrect pixelBuffer size: %lld", __FUNCTION__, bufSize); + ALOGE("%s: Incorrect pixelBuffer size: %" PRId32, __FUNCTION__, bufSize); return BAD_VALUE; } int8_t* img = NULL; @@ -316,20 +321,39 @@ static sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) { if (surface) { anw = android_view_Surface_getNativeWindow(env, surface); if (env->ExceptionCheck()) { - return anw; + return NULL; } } else { jniThrowNullPointerException(env, "surface"); - return anw; + return NULL; } if (anw == NULL) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Surface had no valid native window."); - return anw; + return NULL; } return anw; } +static sp<Surface> getSurface(JNIEnv* env, jobject surface) { + sp<Surface> s; + if (surface) { + s = android_view_Surface_getSurface(env, surface); + if (env->ExceptionCheck()) { + return NULL; + } + } else { + jniThrowNullPointerException(env, "surface"); + return NULL; + } + if (s == NULL) { + jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", + "Surface had no valid native Surface."); + return NULL; + } + return s; +} + extern "C" { static jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) { @@ -456,6 +480,30 @@ static jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, return NO_ERROR; } +static jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) { + ALOGV("nativeGetSurfaceId"); + sp<Surface> s; + if ((s = getSurface(env, surface)) == NULL) { + ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__); + return 0; + } + sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer(); + if (gbp == NULL) { + ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__); + return 0; + } + sp<IBinder> b = gbp->asBinder(); + if (b == NULL) { + ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__); + return 0; + } + /* + * FIXME: Use better unique ID for surfaces than native IBinder pointer. Fix also in the camera + * service (CameraDeviceClient.h). + */ + return reinterpret_cast<jlong>(b.get()); +} + } // extern "C" static JNINativeMethod gCameraDeviceMethods[] = { @@ -477,6 +525,9 @@ static JNINativeMethod gCameraDeviceMethods[] = { { "nativeSetSurfaceDimens", "(Landroid/view/Surface;II)I", (void *)LegacyCameraDevice_nativeSetSurfaceDimens }, + { "nativeGetSurfaceId", + "(Landroid/view/Surface;)J", + (void *)LegacyCameraDevice_nativeGetSurfaceId }, }; // Get all the required offsets in java class and register native functions |