Loading include/gui/SurfaceTexture.h +19 −0 Original line number Diff line number Diff line Loading @@ -26,12 +26,15 @@ #include <ui/GraphicBuffer.h> #include <utils/threads.h> #include <utils/Vector.h> #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture" namespace android { // ---------------------------------------------------------------------------- class IGraphicBufferAlloc; class SurfaceTexture : public BnSurfaceTexture { public: enum { MIN_BUFFER_SLOTS = 3 }; Loading Loading @@ -140,6 +143,12 @@ private: // reset mCurrentTexture to INVALID_BUFFER_SLOT. int mCurrentTexture; // mCurrentTextureBuf is the graphic buffer of the current texture. It's // possible that this buffer is not associated with any buffer slot, so we // must track it separately in order to properly use // IGraphicBufferAlloc::freeAllGraphicBuffersExcept. sp<GraphicBuffer> mCurrentTextureBuf; // mCurrentCrop is the crop rectangle that applies to the current texture. // It gets set to mLastQueuedCrop each time updateTexImage is called. Rect mCurrentCrop; Loading Loading @@ -176,6 +185,16 @@ private: // changed with a call to setTexName. const GLuint mTexName; // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to // allocate new GraphicBuffer objects. sp<IGraphicBufferAlloc> mGraphicBufferAlloc; // mAllocdBuffers is mirror of the list of buffers that SurfaceFlinger is // referencing. This is kept so that gralloc implementations do not need to // properly handle the case where SurfaceFlinger no longer holds a reference // to a buffer, but other processes do. Vector<sp<GraphicBuffer> > mAllocdBuffers; // mMutex is the mutex used to prevent concurrent access to the member // variables of SurfaceTexture objects. It must be locked whenever the // member variables are accessed. Loading include/surfaceflinger/IGraphicBufferAlloc.h 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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. */ #ifndef ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H #define ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H #include <stdint.h> #include <sys/types.h> #include <utils/RefBase.h> #include <binder/IInterface.h> namespace android { // ---------------------------------------------------------------------------- class IGraphicBufferAlloc : public IInterface { public: DECLARE_META_INTERFACE(GraphicBufferAlloc); /* Create a new GraphicBuffer for the client to use. The server will * maintain a reference to the newly created GraphicBuffer until * freeAllGraphicBuffers is called. */ virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) = 0; /* Free all but one of the GraphicBuffer objects that the server is * currently referencing. If bufIndex is not a valid index of the buffers * the server is referencing, then all buffers are freed. */ virtual void freeAllGraphicBuffersExcept(int bufIndex) = 0; }; // ---------------------------------------------------------------------------- class BnGraphicBufferAlloc : public BnInterface<IGraphicBufferAlloc> { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; // ---------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H include/surfaceflinger/ISurfaceComposer.h +6 −8 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <ui/PixelFormat.h> #include <surfaceflinger/ISurfaceComposerClient.h> #include <surfaceflinger/IGraphicBufferAlloc.h> namespace android { // ---------------------------------------------------------------------------- Loading Loading @@ -96,6 +97,10 @@ public: */ virtual sp<ISurfaceComposerClient> createClientConnection() = 0; /* create a graphic buffer allocator */ virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0; /* retrieve the control block */ virtual sp<IMemoryHeap> getCblk() const = 0; Loading Loading @@ -131,13 +136,6 @@ public: * This is an ASYNCHRONOUS call. */ virtual void signal() const = 0; /* Create a new GraphicBuffer for the client to use. SurfaceFlinger will * not maintain a reference to the GraphicBuffer, so the underlying native * handle will be freed once the client references are released. */ virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) const = 0; }; // ---------------------------------------------------------------------------- Loading @@ -151,7 +149,7 @@ public: BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, CREATE_CONNECTION, CREATE_CLIENT_CONNECTION, CREATE_GRAPHIC_BUFFER, CREATE_GRAPHIC_BUFFER_ALLOC, GET_CBLK, OPEN_GLOBAL_TRANSACTION, CLOSE_GLOBAL_TRANSACTION, Loading libs/gui/SurfaceTexture.cpp +30 −13 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/SurfaceComposerClient.h> #include <surfaceflinger/IGraphicBufferAlloc.h> #include <utils/Log.h> Loading Loading @@ -83,6 +84,8 @@ SurfaceTexture::SurfaceTexture(GLuint tex) : mSlots[i].mEglDisplay = EGL_NO_DISPLAY; mSlots[i].mOwnedByClient = false; } sp<ISurfaceComposer> composer(ComposerService::getComposerService()); mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); } SurfaceTexture::~SurfaceTexture() { Loading Loading @@ -110,9 +113,8 @@ sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf, return 0; } usage |= GraphicBuffer::USAGE_HW_TEXTURE; sp<ISurfaceComposer> composer(ComposerService::getComposerService()); sp<GraphicBuffer> graphicBuffer(composer->createGraphicBuffer(w, h, format, usage)); sp<GraphicBuffer> graphicBuffer( mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage)); if (graphicBuffer == 0) { LOGE("requestBuffer: SurfaceComposer::createGraphicBuffer failed"); } else { Loading @@ -122,6 +124,7 @@ sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf, mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR; mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; } mAllocdBuffers.add(graphicBuffer); } return graphicBuffer; } Loading Loading @@ -204,27 +207,28 @@ status_t SurfaceTexture::updateTexImage() { // Initially both mCurrentTexture and mLastQueued are INVALID_BUFFER_SLOT, // so this check will fail until a buffer gets queued. if (mCurrentTexture != mLastQueued) { // Update the SurfaceTexture state. mCurrentTexture = mLastQueued; mCurrentCrop = mLastQueuedCrop; mCurrentTransform = mLastQueuedTransform; // Update the GL texture object. EGLImageKHR image = mSlots[mCurrentTexture].mEglImage; EGLImageKHR image = mSlots[mLastQueued].mEglImage; if (image == EGL_NO_IMAGE_KHR) { EGLDisplay dpy = eglGetCurrentDisplay(); sp<GraphicBuffer> graphicBuffer = mSlots[mCurrentTexture].mGraphicBuffer; sp<GraphicBuffer> graphicBuffer = mSlots[mLastQueued].mGraphicBuffer; image = createImage(dpy, graphicBuffer); mSlots[mCurrentTexture].mEglImage = image; mSlots[mCurrentTexture].mEglDisplay = dpy; mSlots[mLastQueued].mEglImage = image; mSlots[mLastQueued].mEglDisplay = dpy; } glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image); GLint error = glGetError(); if (error != GL_NO_ERROR) { LOGE("error binding external texture image %p (slot %d): %#04x", image, mCurrentTexture, error); image, mLastQueued, error); return -EINVAL; } // Update the SurfaceTexture state. mCurrentTexture = mLastQueued; mCurrentTextureBuf = mSlots[mCurrentTexture].mGraphicBuffer; mCurrentCrop = mLastQueuedCrop; mCurrentTransform = mLastQueuedTransform; } return OK; } Loading Loading @@ -282,6 +286,19 @@ void SurfaceTexture::freeAllBuffers() { mSlots[i].mEglDisplay = EGL_NO_DISPLAY; } } int exceptBuf = -1; for (size_t i = 0; i < mAllocdBuffers.size(); i++) { if (mAllocdBuffers[i] == mCurrentTextureBuf) { exceptBuf = i; break; } } mAllocdBuffers.clear(); if (exceptBuf >= 0) { mAllocdBuffers.add(mCurrentTextureBuf); } mGraphicBufferAlloc->freeAllGraphicBuffersExcept(exceptBuf); } EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy, Loading libs/surfaceflinger_client/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ LOCAL_SRC_FILES:= \ ISurfaceComposer.cpp \ ISurface.cpp \ ISurfaceComposerClient.cpp \ IGraphicBufferAlloc.cpp \ LayerState.cpp \ SharedBufferStack.cpp \ Surface.cpp \ Loading Loading
include/gui/SurfaceTexture.h +19 −0 Original line number Diff line number Diff line Loading @@ -26,12 +26,15 @@ #include <ui/GraphicBuffer.h> #include <utils/threads.h> #include <utils/Vector.h> #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture" namespace android { // ---------------------------------------------------------------------------- class IGraphicBufferAlloc; class SurfaceTexture : public BnSurfaceTexture { public: enum { MIN_BUFFER_SLOTS = 3 }; Loading Loading @@ -140,6 +143,12 @@ private: // reset mCurrentTexture to INVALID_BUFFER_SLOT. int mCurrentTexture; // mCurrentTextureBuf is the graphic buffer of the current texture. It's // possible that this buffer is not associated with any buffer slot, so we // must track it separately in order to properly use // IGraphicBufferAlloc::freeAllGraphicBuffersExcept. sp<GraphicBuffer> mCurrentTextureBuf; // mCurrentCrop is the crop rectangle that applies to the current texture. // It gets set to mLastQueuedCrop each time updateTexImage is called. Rect mCurrentCrop; Loading Loading @@ -176,6 +185,16 @@ private: // changed with a call to setTexName. const GLuint mTexName; // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to // allocate new GraphicBuffer objects. sp<IGraphicBufferAlloc> mGraphicBufferAlloc; // mAllocdBuffers is mirror of the list of buffers that SurfaceFlinger is // referencing. This is kept so that gralloc implementations do not need to // properly handle the case where SurfaceFlinger no longer holds a reference // to a buffer, but other processes do. Vector<sp<GraphicBuffer> > mAllocdBuffers; // mMutex is the mutex used to prevent concurrent access to the member // variables of SurfaceTexture objects. It must be locked whenever the // member variables are accessed. Loading
include/surfaceflinger/IGraphicBufferAlloc.h 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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. */ #ifndef ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H #define ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H #include <stdint.h> #include <sys/types.h> #include <utils/RefBase.h> #include <binder/IInterface.h> namespace android { // ---------------------------------------------------------------------------- class IGraphicBufferAlloc : public IInterface { public: DECLARE_META_INTERFACE(GraphicBufferAlloc); /* Create a new GraphicBuffer for the client to use. The server will * maintain a reference to the newly created GraphicBuffer until * freeAllGraphicBuffers is called. */ virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) = 0; /* Free all but one of the GraphicBuffer objects that the server is * currently referencing. If bufIndex is not a valid index of the buffers * the server is referencing, then all buffers are freed. */ virtual void freeAllGraphicBuffersExcept(int bufIndex) = 0; }; // ---------------------------------------------------------------------------- class BnGraphicBufferAlloc : public BnInterface<IGraphicBufferAlloc> { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; // ---------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
include/surfaceflinger/ISurfaceComposer.h +6 −8 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <ui/PixelFormat.h> #include <surfaceflinger/ISurfaceComposerClient.h> #include <surfaceflinger/IGraphicBufferAlloc.h> namespace android { // ---------------------------------------------------------------------------- Loading Loading @@ -96,6 +97,10 @@ public: */ virtual sp<ISurfaceComposerClient> createClientConnection() = 0; /* create a graphic buffer allocator */ virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0; /* retrieve the control block */ virtual sp<IMemoryHeap> getCblk() const = 0; Loading Loading @@ -131,13 +136,6 @@ public: * This is an ASYNCHRONOUS call. */ virtual void signal() const = 0; /* Create a new GraphicBuffer for the client to use. SurfaceFlinger will * not maintain a reference to the GraphicBuffer, so the underlying native * handle will be freed once the client references are released. */ virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) const = 0; }; // ---------------------------------------------------------------------------- Loading @@ -151,7 +149,7 @@ public: BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, CREATE_CONNECTION, CREATE_CLIENT_CONNECTION, CREATE_GRAPHIC_BUFFER, CREATE_GRAPHIC_BUFFER_ALLOC, GET_CBLK, OPEN_GLOBAL_TRANSACTION, CLOSE_GLOBAL_TRANSACTION, Loading
libs/gui/SurfaceTexture.cpp +30 −13 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/SurfaceComposerClient.h> #include <surfaceflinger/IGraphicBufferAlloc.h> #include <utils/Log.h> Loading Loading @@ -83,6 +84,8 @@ SurfaceTexture::SurfaceTexture(GLuint tex) : mSlots[i].mEglDisplay = EGL_NO_DISPLAY; mSlots[i].mOwnedByClient = false; } sp<ISurfaceComposer> composer(ComposerService::getComposerService()); mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); } SurfaceTexture::~SurfaceTexture() { Loading Loading @@ -110,9 +113,8 @@ sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf, return 0; } usage |= GraphicBuffer::USAGE_HW_TEXTURE; sp<ISurfaceComposer> composer(ComposerService::getComposerService()); sp<GraphicBuffer> graphicBuffer(composer->createGraphicBuffer(w, h, format, usage)); sp<GraphicBuffer> graphicBuffer( mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage)); if (graphicBuffer == 0) { LOGE("requestBuffer: SurfaceComposer::createGraphicBuffer failed"); } else { Loading @@ -122,6 +124,7 @@ sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf, mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR; mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; } mAllocdBuffers.add(graphicBuffer); } return graphicBuffer; } Loading Loading @@ -204,27 +207,28 @@ status_t SurfaceTexture::updateTexImage() { // Initially both mCurrentTexture and mLastQueued are INVALID_BUFFER_SLOT, // so this check will fail until a buffer gets queued. if (mCurrentTexture != mLastQueued) { // Update the SurfaceTexture state. mCurrentTexture = mLastQueued; mCurrentCrop = mLastQueuedCrop; mCurrentTransform = mLastQueuedTransform; // Update the GL texture object. EGLImageKHR image = mSlots[mCurrentTexture].mEglImage; EGLImageKHR image = mSlots[mLastQueued].mEglImage; if (image == EGL_NO_IMAGE_KHR) { EGLDisplay dpy = eglGetCurrentDisplay(); sp<GraphicBuffer> graphicBuffer = mSlots[mCurrentTexture].mGraphicBuffer; sp<GraphicBuffer> graphicBuffer = mSlots[mLastQueued].mGraphicBuffer; image = createImage(dpy, graphicBuffer); mSlots[mCurrentTexture].mEglImage = image; mSlots[mCurrentTexture].mEglDisplay = dpy; mSlots[mLastQueued].mEglImage = image; mSlots[mLastQueued].mEglDisplay = dpy; } glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image); GLint error = glGetError(); if (error != GL_NO_ERROR) { LOGE("error binding external texture image %p (slot %d): %#04x", image, mCurrentTexture, error); image, mLastQueued, error); return -EINVAL; } // Update the SurfaceTexture state. mCurrentTexture = mLastQueued; mCurrentTextureBuf = mSlots[mCurrentTexture].mGraphicBuffer; mCurrentCrop = mLastQueuedCrop; mCurrentTransform = mLastQueuedTransform; } return OK; } Loading Loading @@ -282,6 +286,19 @@ void SurfaceTexture::freeAllBuffers() { mSlots[i].mEglDisplay = EGL_NO_DISPLAY; } } int exceptBuf = -1; for (size_t i = 0; i < mAllocdBuffers.size(); i++) { if (mAllocdBuffers[i] == mCurrentTextureBuf) { exceptBuf = i; break; } } mAllocdBuffers.clear(); if (exceptBuf >= 0) { mAllocdBuffers.add(mCurrentTextureBuf); } mGraphicBufferAlloc->freeAllGraphicBuffersExcept(exceptBuf); } EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy, Loading
libs/surfaceflinger_client/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ LOCAL_SRC_FILES:= \ ISurfaceComposer.cpp \ ISurface.cpp \ ISurfaceComposerClient.cpp \ IGraphicBufferAlloc.cpp \ LayerState.cpp \ SharedBufferStack.cpp \ Surface.cpp \ Loading