protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mSurface != null) {
- nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+ mSurface.setDefaultBufferSize(getWidth(), getHeight());
updateLayer();
if (mListener != null) {
mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight());
// Create a new SurfaceTexture for the layer.
mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
}
- nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+ mSurface.setDefaultBufferSize(getWidth(), getHeight());
nCreateNativeWindow(mSurface);
mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() {
mMatrixChanged = true;
mAttachInfo.mHardwareRenderer.setSurfaceTexture(mLayer, mSurface);
- nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+ mSurface.setDefaultBufferSize(getWidth(), getHeight());
}
applyUpdate();
private native void nCreateNativeWindow(SurfaceTexture surface);
private native void nDestroyNativeWindow();
- private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture,
- int width, int height);
-
private static native boolean nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty);
private static native void nUnlockCanvasAndPost(int nativeWindow, Canvas canvas);
}
struct fields_t {
jfieldID surfaceTexture;
+ jfieldID bufferQueue;
jfieldID frameAvailableListener;
jmethodID postEvent;
};
env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get());
}
+static void SurfaceTexture_setBufferQueue(JNIEnv* env, jobject thiz,
+ const sp<BufferQueue>& bq)
+{
+ BufferQueue* const p =
+ (BufferQueue*)env->GetIntField(thiz, fields.bufferQueue);
+ if (bq.get()) {
+ bq->incStrong((void*)SurfaceTexture_setBufferQueue);
+ }
+ if (p) {
+ p->decStrong((void*)SurfaceTexture_setBufferQueue);
+ }
+ env->SetIntField(thiz, fields.bufferQueue, (int)bq.get());
+}
+
static void SurfaceTexture_setFrameAvailableListener(JNIEnv* env,
jobject thiz, sp<GLConsumer::FrameAvailableListener> listener)
{
env->SetIntField(thiz, fields.frameAvailableListener, (int)listener.get());
}
-sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env,
- jobject thiz)
-{
+sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) {
return (GLConsumer*)env->GetIntField(thiz, fields.surfaceTexture);
}
-sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
- JNIEnv* env, jobject thiz)
-{
+sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) {
+ return (BufferQueue*)env->GetIntField(thiz, fields.bufferQueue);
+}
+
+sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz) {
sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
- sp<Surface> surfaceTextureClient(surfaceTexture != NULL ?
- new Surface(surfaceTexture->getBufferQueue()) : NULL);
+ sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, thiz));
+ sp<Surface> surfaceTextureClient(surfaceTexture != NULL ? new Surface(producer) : NULL);
return surfaceTextureClient;
}
-bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz)
-{
+bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) {
jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
return env->IsInstanceOf(thiz, surfaceTextureClass);
}
// ----------------------------------------------------------------------------
+
+#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
+#define ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID "mBufferQueue"
+#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
+ "mFrameAvailableListener"
+
static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
{
fields.surfaceTexture = env->GetFieldID(clazz,
ALOGE("can't find android/graphics/SurfaceTexture.%s",
ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
}
+ fields.bufferQueue = env->GetFieldID(clazz,
+ ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID, "I");
+ if (fields.bufferQueue == NULL) {
+ ALOGE("can't find android/graphics/SurfaceTexture.%s",
+ ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID);
+ }
fields.frameAvailableListener = env->GetFieldID(clazz,
ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID, "I");
if (fields.frameAvailableListener == NULL) {
return;
}
SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
+ SurfaceTexture_setBufferQueue(env, thiz, bq);
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
surfaceTexture->setFrameAvailableListener(0);
SurfaceTexture_setFrameAvailableListener(env, thiz, 0);
SurfaceTexture_setSurfaceTexture(env, thiz, 0);
+ SurfaceTexture_setBufferQueue(env, thiz, 0);
}
static void SurfaceTexture_setDefaultBufferSize(
- JNIEnv* env, jobject thiz, jint width, jint height)
-{
+ JNIEnv* env, jobject thiz, jint width, jint height) {
sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
surfaceTexture->setDefaultBufferSize(width, height);
}
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return;
- sp<BufferQueue> bufferQueue = NULL;
+ sp<IGraphicBufferProducer> producer = NULL;
if (jSurfaceTexture != NULL) {
- sp<GLConsumer> surfaceTexture =
- SurfaceTexture_getSurfaceTexture(env, jSurfaceTexture);
- if (surfaceTexture != NULL) {
- bufferQueue = surfaceTexture->getBufferQueue();
- }
- else {
+ producer = SurfaceTexture_getProducer(env, jSurfaceTexture);
+ if (producer == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException",
"SurfaceTexture already released in setPreviewTexture");
return;
}
- if (camera->setPreviewTexture(bufferQueue) != NO_ERROR) {
+ if (camera->setPreviewTexture(producer) != NO_ERROR) {
jniThrowException(env, "java/io/IOException",
"setPreviewTexture failed");
}
jint _remaining;
EGLint *attrib_list = (EGLint *) 0;
android::sp<ANativeWindow> window;
- android::sp<android::GLConsumer> glConsumer;
+ android::sp<android::IGraphicBufferProducer> producer;
if (!attrib_list_ref) {
_exception = 1;
_exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface";
goto exit;
}
- glConsumer = android::SurfaceTexture_getSurfaceTexture(_env, win);
+ producer = android::SurfaceTexture_getProducer(_env, win);
- if (glConsumer == NULL)
+ if (producer == NULL)
goto not_valid_surface;
- window = new android::Surface(glConsumer->getBufferQueue());
+ window = new android::Surface(producer);
if (window == NULL)
goto not_valid_surface;
static jint nativeCreateFromSurfaceTexture(JNIEnv* env, jclass clazz,
jobject surfaceTextureObj) {
- sp<GLConsumer> st(SurfaceTexture_getSurfaceTexture(env, surfaceTextureObj));
- if (st == NULL) {
+ sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, surfaceTextureObj));
+ if (producer == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException",
"SurfaceTexture has already been released");
return 0;
}
- sp<IGraphicBufferProducer> bq = st->getBufferQueue();
- sp<Surface> surface(new Surface(bq, true));
+ sp<Surface> surface(new Surface(producer, true));
if (surface == NULL) {
jniThrowException(env, OutOfResourcesException, NULL);
return 0;
// Native layer
// ----------------------------------------------------------------------------
-static void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject,
- jobject surface, jint width, jint height) {
-
- sp<GLConsumer> glConsumer(SurfaceTexture_getSurfaceTexture(env, surface));
- glConsumer->setDefaultBufferSize(width, height);
-}
-
static inline SkBitmap::Config convertPixelFormat(int32_t format) {
switch (format) {
case WINDOW_FORMAT_RGBA_8888:
static void android_view_TextureView_createNativeWindow(JNIEnv* env, jobject textureView,
jobject surface) {
- sp<GLConsumer> glConsumer(SurfaceTexture_getSurfaceTexture(env, surface));
- sp<ANativeWindow> window = new Surface(glConsumer->getBufferQueue());
+ sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, surface));
+ sp<ANativeWindow> window = new Surface(producer);
window->incStrong((void*)android_view_TextureView_createNativeWindow);
SET_INT(textureView, gTextureViewClassInfo.nativeWindow, jint(window.get()));
const char* const kClassPathName = "android/view/TextureView";
static JNINativeMethod gMethods[] = {
- { "nSetDefaultBufferSize", "(Landroid/graphics/SurfaceTexture;II)V",
- (void*) android_view_TextureView_setDefaultBufferSize },
-
{ "nCreateNativeWindow", "(Landroid/graphics/SurfaceTexture;)V",
(void*) android_view_TextureView_createNativeWindow },
{ "nDestroyNativeWindow", "()V",
return 0;
}
- sp<GLConsumer> glConsumer(SurfaceTexture_getSurfaceTexture(_env, native_window));
-
- window = new Surface(glConsumer->getBufferQueue());
+ sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(_env, native_window));
+ window = new Surface(producer);
if (window == NULL)
goto not_valid_surface;
* These fields are used by native code, do not access or modify.
*/
private int mSurfaceTexture;
+ private int mBufferQueue;
private int mFrameAvailableListener;
/**
namespace android {
class GLConsumer;
+class IGraphicBufferProducer;
-extern sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
- JNIEnv* env, jobject thiz);
+extern sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz);
extern bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz);
/* Gets the underlying GLConsumer from a SurfaceTexture Java object. */
extern sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz);
+/* gets the producer end of the SurfaceTexture */
+extern sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz);
+
} // namespace android
#endif // _ANDROID_GRAPHICS_SURFACETEXTURE_H
void returnLockedBuffer(CpuConsumer::LockedBuffer* buffer);
+ void setCpuConsumer(const sp<CpuConsumer>& consumer) { mConsumer = consumer; }
CpuConsumer* getCpuConsumer() { return mConsumer.get(); }
- void setCpuConsumer(sp<CpuConsumer> consumer) { mConsumer = consumer; }
+ void setBufferQueue(const sp<BufferQueue>& bq) { mBufferQueue = bq; }
+ BufferQueue* getBufferQueue() { return mBufferQueue.get(); }
void setBufferFormat(int format) { mFormat = format; }
int getBufferFormat() { return mFormat; }
List<CpuConsumer::LockedBuffer*> mBuffers;
sp<CpuConsumer> mConsumer;
+ sp<BufferQueue> mBufferQueue;
jobject mWeakThiz;
jclass mClazz;
int mFormat;
return ctx->getCpuConsumer();
}
+static BufferQueue* ImageReader_getBufferQueue(JNIEnv* env, jobject thiz)
+{
+ ALOGV("%s:", __FUNCTION__);
+ JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz);
+ if (ctx == NULL) {
+ jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
+ return NULL;
+ }
+ return ctx->getBufferQueue();
+}
+
static void ImageReader_setNativeContext(JNIEnv* env,
jobject thiz, sp<JNIImageReaderContext> ctx)
{
}
sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages));
ctx->setCpuConsumer(consumer);
+ ctx->setBufferQueue(bq);
consumer->setFrameAvailableListener(ctx);
ImageReader_setNativeContext(env, thiz, ctx);
ctx->setBufferFormat(nativeFormat);
{
ALOGV("%s: ", __FUNCTION__);
- CpuConsumer* consumer = ImageReader_getCpuConsumer(env, thiz);
- if (consumer == NULL) {
+ BufferQueue* bq = ImageReader_getBufferQueue(env, thiz);
+ if (bq == NULL) {
jniThrowRuntimeException(env, "CpuConsumer is uninitialized");
return NULL;
}
// Wrap the IGBP in a Java-language Surface.
- return android_view_Surface_createFromIGraphicBufferProducer(
- env, consumer->getProducerInterface());
+ return android_view_Surface_createFromIGraphicBufferProducer(env, bq);
}
static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx)
// Create dummy surface using a GLConsumer
sp<BufferQueue> bq = new BufferQueue();
surfaceTexture_ = new GLConsumer(bq, 0);
- window_ = new Surface(static_cast<sp<IGraphicBufferProducer> >(
- surfaceTexture_->getBufferQueue()));
+ window_ = new Surface(static_cast<sp<IGraphicBufferProducer> >(bq));
surfaces_[0] = SurfaceWindowPair(eglCreateWindowSurface(display(), config, window_.get(), NULL), NULL);
if (CheckEGLError("eglCreateWindowSurface")) return false;