summaryrefslogtreecommitdiffstats
path: root/libs/gui/Surface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gui/Surface.cpp')
-rw-r--r--libs/gui/Surface.cpp634
1 files changed, 64 insertions, 570 deletions
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 0c5767b..4d1d923 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -21,13 +21,15 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
#include <utils/CallStack.h>
+#include <utils/Errors.h>
#include <utils/Log.h>
+#include <utils/threads.h>
-#include <binder/IPCThreadState.h>
#include <binder/IMemory.h>
+#include <binder/IPCThreadState.h>
+
+#include <gui/SurfaceTextureClient.h>
#include <ui/DisplayInfo.h>
#include <ui/GraphicBuffer.h>
@@ -35,12 +37,11 @@
#include <ui/GraphicLog.h>
#include <ui/Rect.h>
-#include <surfaceflinger/Surface.h>
#include <surfaceflinger/ISurface.h>
#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
#include <surfaceflinger/SurfaceComposerClient.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
#include <private/surfaceflinger/LayerState.h>
namespace android {
@@ -273,58 +274,10 @@ sp<Surface> SurfaceControl::getSurface() const
// Surface
// ============================================================================
-class SurfaceClient : public Singleton<SurfaceClient>
-{
- // all these attributes are constants
- sp<ISurfaceComposer> mComposerService;
- sp<ISurfaceComposerClient> mClient;
- status_t mStatus;
- SharedClient* mControl;
- sp<IMemoryHeap> mControlMemory;
-
- SurfaceClient()
- : Singleton<SurfaceClient>(), mStatus(NO_INIT)
- {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- mComposerService = sf;
- mClient = sf->createClientConnection();
- if (mClient != NULL) {
- mControlMemory = mClient->getControlBlock();
- if (mControlMemory != NULL) {
- mControl = static_cast<SharedClient *>(
- mControlMemory->getBase());
- if (mControl) {
- mStatus = NO_ERROR;
- }
- }
- }
- }
- friend class Singleton<SurfaceClient>;
-public:
- status_t initCheck() const {
- return mStatus;
- }
- SharedClient* getSharedClient() const {
- return mControl;
- }
- ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
- // TODO: we could cache a few tokens here to avoid an IPC
- return mClient->getTokenForSurface(sur);
- }
- void signalServer() const {
- mComposerService->signal();
- }
-};
-
-ANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient);
-
// ---------------------------------------------------------------------------
Surface::Surface(const sp<SurfaceControl>& surface)
- : mBufferMapper(GraphicBufferMapper::get()),
- mClient(SurfaceClient::getInstance()),
- mSharedBufferClient(NULL),
- mInitCheck(NO_INIT),
+ : mInitCheck(NO_INIT),
mSurface(surface->mSurface),
mIdentity(surface->mIdentity),
mFormat(surface->mFormat), mFlags(surface->mFlags),
@@ -334,10 +287,7 @@ Surface::Surface(const sp<SurfaceControl>& surface)
}
Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
- : mBufferMapper(GraphicBufferMapper::get()),
- mClient(SurfaceClient::getInstance()),
- mSharedBufferClient(NULL),
- mInitCheck(NO_INIT)
+ : mInitCheck(NO_INIT)
{
mSurface = interface_cast<ISurface>(ref);
mIdentity = parcel.readInt32();
@@ -382,7 +332,6 @@ status_t Surface::writeToParcel(
}
-
Mutex Surface::sCachedSurfacesLock;
DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces;
@@ -422,32 +371,29 @@ void Surface::init()
ANativeWindow::query = query;
ANativeWindow::perform = perform;
- DisplayInfo dinfo;
- SurfaceComposerClient::getDisplayInfo(0, &dinfo);
- const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
- const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
- // FIXME: set real values here
- const_cast<int&>(ANativeWindow::minSwapInterval) = 1;
- const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
- const_cast<uint32_t&>(ANativeWindow::flags) = 0;
-
- mNextBufferTransform = 0;
- mConnected = 0;
- mSwapRectangle.makeInvalid();
- mNextBufferCrop = Rect(0,0);
- // two buffers by default
- mBuffers.setCapacity(2);
- mBuffers.insertAt(0, 2);
-
- if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
- int32_t token = mClient.getTokenForSurface(mSurface);
- if (token >= 0) {
- mSharedBufferClient = new SharedBufferClient(
- mClient.getSharedClient(), token, 2, mIdentity);
- mInitCheck = mClient.getSharedClient()->validate(token);
- } else {
- LOGW("Not initializing the shared buffer client because token = %d",
- token);
+ if (mSurface != NULL) {
+ sp<ISurfaceTexture> surfaceTexture(mSurface->getSurfaceTexture());
+ LOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface");
+ if (surfaceTexture != NULL) {
+ mSurfaceTextureClient = new SurfaceTextureClient(surfaceTexture);
+ mSurfaceTextureClient->setUsage(GraphicBuffer::USAGE_HW_RENDER);
+ }
+
+ DisplayInfo dinfo;
+ SurfaceComposerClient::getDisplayInfo(0, &dinfo);
+ const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
+ const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
+
+ const_cast<int&>(ANativeWindow::minSwapInterval) =
+ mSurfaceTextureClient->minSwapInterval;
+
+ const_cast<int&>(ANativeWindow::maxSwapInterval) =
+ mSurfaceTextureClient->maxSwapInterval;
+
+ const_cast<uint32_t&>(ANativeWindow::flags) = 0;
+
+ if (mSurfaceTextureClient != 0) {
+ mInitCheck = NO_ERROR;
}
}
}
@@ -456,9 +402,8 @@ Surface::~Surface()
{
// clear all references and trigger an IPC now, to make sure things
// happen without delay, since these resources are quite heavy.
- mBuffers.clear();
+ mSurfaceTextureClient.clear();
mSurface.clear();
- delete mSharedBufferClient;
IPCThreadState::self()->flushCommands();
}
@@ -473,32 +418,6 @@ status_t Surface::validate(bool inCancelBuffer) const
LOGE("invalid token (identity=%u)", mIdentity);
return mInitCheck;
}
-
- // verify the identity of this surface
- uint32_t identity = mSharedBufferClient->getIdentity();
- if (mIdentity != identity) {
- LOGE("[Surface] using an invalid surface, "
- "identity=%u should be %d",
- mIdentity, identity);
- CallStack stack;
- stack.update();
- stack.dump("Surface");
- return BAD_INDEX;
- }
-
- // check the surface didn't become invalid
- status_t err = mSharedBufferClient->getStatus();
- if (err != NO_ERROR) {
- if (!inCancelBuffer) {
- LOGE("surface (identity=%u) is invalid, err=%d (%s)",
- mIdentity, err, strerror(-err));
- CallStack stack;
- stack.update();
- stack.dump("Surface");
- }
- return err;
- }
-
return NO_ERROR;
}
@@ -509,7 +428,8 @@ sp<IBinder> Surface::asBinder() const {
// ----------------------------------------------------------------------------
int Surface::setSwapInterval(ANativeWindow* window, int interval) {
- return 0;
+ Surface* self = getSelf(window);
+ return self->setSwapInterval(interval);
}
int Surface::dequeueBuffer(ANativeWindow* window,
@@ -554,383 +474,52 @@ int Surface::perform(ANativeWindow* window,
// ----------------------------------------------------------------------------
-bool Surface::needNewBuffer(int bufIdx,
- uint32_t *pWidth, uint32_t *pHeight,
- uint32_t *pFormat, uint32_t *pUsage) const
-{
- Mutex::Autolock _l(mSurfaceLock);
-
- // Always call needNewBuffer(), since it clears the needed buffers flags
- bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
- bool validBuffer = mBufferInfo.validateBuffer(mBuffers[bufIdx]);
- bool newNeewBuffer = needNewBuffer || !validBuffer;
- if (newNeewBuffer) {
- mBufferInfo.get(pWidth, pHeight, pFormat, pUsage);
- }
- return newNeewBuffer;
+int Surface::setSwapInterval(int interval) {
+ return mSurfaceTextureClient->setSwapInterval(interval);
}
-int Surface::dequeueBuffer(ANativeWindowBuffer** buffer)
-{
- status_t err = validate();
- if (err != NO_ERROR)
- return err;
-
- GraphicLog& logger(GraphicLog::getInstance());
- logger.log(GraphicLog::SF_APP_DEQUEUE_BEFORE, mIdentity, -1);
-
- ssize_t bufIdx = mSharedBufferClient->dequeue();
-
- logger.log(GraphicLog::SF_APP_DEQUEUE_AFTER, mIdentity, bufIdx);
-
- if (bufIdx < 0) {
- LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
- return bufIdx;
- }
-
- // grow the buffer array if needed
- const size_t size = mBuffers.size();
- const size_t needed = bufIdx+1;
- if (size < needed) {
- mBuffers.insertAt(size, needed-size);
- }
-
- uint32_t w, h, format, usage;
- if (needNewBuffer(bufIdx, &w, &h, &format, &usage)) {
- err = getBufferLocked(bufIdx, w, h, format, usage);
- LOGE_IF(err, "getBufferLocked(%ld, %u, %u, %u, %08x) failed (%s)",
- bufIdx, w, h, format, usage, strerror(-err));
- if (err == NO_ERROR) {
- // reset the width/height with the what we get from the buffer
- const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
- mWidth = uint32_t(backBuffer->width);
- mHeight = uint32_t(backBuffer->height);
- }
- }
-
- // if we still don't have a buffer here, we probably ran out of memory
- const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
- if (!err && backBuffer==0) {
- err = NO_MEMORY;
- }
-
+int Surface::dequeueBuffer(ANativeWindowBuffer** buffer) {
+ status_t err = mSurfaceTextureClient->dequeueBuffer(buffer);
if (err == NO_ERROR) {
- mDirtyRegion.set(backBuffer->width, backBuffer->height);
- *buffer = backBuffer.get();
- } else {
- mSharedBufferClient->undoDequeue(bufIdx);
+ mDirtyRegion.set(buffer[0]->width, buffer[0]->height);
}
-
return err;
}
-int Surface::cancelBuffer(ANativeWindowBuffer* buffer)
-{
- status_t err = validate(true);
- switch (err) {
- case NO_ERROR:
- // no error, common case
- break;
- case BAD_INDEX:
- // legitimate errors here
- return err;
- default:
- // other errors happen because the surface is now invalid,
- // for instance because it has been destroyed. In this case,
- // we just fail silently (canceling a buffer is not technically
- // an error at this point)
- return NO_ERROR;
- }
-
- int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
-
- err = mSharedBufferClient->cancel(bufIdx);
-
- LOGE_IF(err, "error canceling buffer %d (%s)", bufIdx, strerror(-err));
- return err;
+int Surface::cancelBuffer(ANativeWindowBuffer* buffer) {
+ return mSurfaceTextureClient->cancelBuffer(buffer);
}
-
-int Surface::lockBuffer(ANativeWindowBuffer* buffer)
-{
- status_t err = validate();
- if (err != NO_ERROR)
- return err;
-
- int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
-
- GraphicLog& logger(GraphicLog::getInstance());
- logger.log(GraphicLog::SF_APP_LOCK_BEFORE, mIdentity, bufIdx);
-
- err = mSharedBufferClient->lock(bufIdx);
-
- logger.log(GraphicLog::SF_APP_LOCK_AFTER, mIdentity, bufIdx);
-
- LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
- return err;
+int Surface::lockBuffer(ANativeWindowBuffer* buffer) {
+ return mSurfaceTextureClient->lockBuffer(buffer);
}
-int Surface::queueBuffer(ANativeWindowBuffer* buffer)
-{
- status_t err = validate();
- if (err != NO_ERROR)
- return err;
-
- if (mSwapRectangle.isValid()) {
- mDirtyRegion.set(mSwapRectangle);
- }
-
- int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
-
- GraphicLog::getInstance().log(GraphicLog::SF_APP_QUEUE, mIdentity, bufIdx);
-
- mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform);
- mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
- mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
- err = mSharedBufferClient->queue(bufIdx);
- LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
-
- if (err == NO_ERROR) {
- // TODO: can we avoid this IPC if we know there is one pending?
- mClient.signalServer();
- }
- return err;
+int Surface::queueBuffer(ANativeWindowBuffer* buffer) {
+ return mSurfaceTextureClient->queueBuffer(buffer);
}
-int Surface::query(int what, int* value) const
-{
+int Surface::query(int what, int* value) const {
switch (what) {
- case NATIVE_WINDOW_WIDTH:
- *value = int(mWidth);
- return NO_ERROR;
- case NATIVE_WINDOW_HEIGHT:
- *value = int(mHeight);
- return NO_ERROR;
- case NATIVE_WINDOW_FORMAT:
- *value = int(mFormat);
+ case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+ // TODO: this is not needed anymore
+ *value = 1;
return NO_ERROR;
- case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
- *value = MIN_UNDEQUEUED_BUFFERS;
- return NO_ERROR;
- case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- *value = sf->authenticateSurface(mSurface) ? 1 : 0;
- return NO_ERROR;
- }
case NATIVE_WINDOW_CONCRETE_TYPE:
+ // TODO: this is not needed anymore
*value = NATIVE_WINDOW_SURFACE;
return NO_ERROR;
}
- return BAD_VALUE;
-}
-
-int Surface::perform(int operation, va_list args)
-{
- status_t err = validate();
- if (err != NO_ERROR)
- return err;
-
- int res = NO_ERROR;
- switch (operation) {
- case NATIVE_WINDOW_SET_USAGE:
- dispatch_setUsage( args );
- break;
- case NATIVE_WINDOW_CONNECT:
- res = dispatch_connect( args );
- break;
- case NATIVE_WINDOW_DISCONNECT:
- res = dispatch_disconnect( args );
- break;
- case NATIVE_WINDOW_SET_CROP:
- res = dispatch_crop( args );
- break;
- case NATIVE_WINDOW_SET_BUFFER_COUNT:
- res = dispatch_set_buffer_count( args );
- break;
- case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
- res = dispatch_set_buffers_geometry( args );
- break;
- case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
- res = dispatch_set_buffers_transform( args );
- break;
- case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
- res = dispatch_set_buffers_timestamp( args );
- break;
- default:
- res = NAME_NOT_FOUND;
- break;
- }
- return res;
-}
-
-void Surface::dispatch_setUsage(va_list args) {
- int usage = va_arg(args, int);
- setUsage( usage );
-}
-int Surface::dispatch_connect(va_list args) {
- int api = va_arg(args, int);
- return connect( api );
-}
-int Surface::dispatch_disconnect(va_list args) {
- int api = va_arg(args, int);
- return disconnect( api );
-}
-int Surface::dispatch_crop(va_list args) {
- android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
- return crop( reinterpret_cast<Rect const*>(rect) );
-}
-int Surface::dispatch_set_buffer_count(va_list args) {
- size_t bufferCount = va_arg(args, size_t);
- return setBufferCount(bufferCount);
-}
-int Surface::dispatch_set_buffers_geometry(va_list args) {
- int w = va_arg(args, int);
- int h = va_arg(args, int);
- int f = va_arg(args, int);
- return setBuffersGeometry(w, h, f);
-}
-
-int Surface::dispatch_set_buffers_transform(va_list args) {
- int transform = va_arg(args, int);
- return setBuffersTransform(transform);
-}
-
-int Surface::dispatch_set_buffers_timestamp(va_list args) {
- int64_t timestamp = va_arg(args, int64_t);
- return setBuffersTimestamp(timestamp);
-}
-
-void Surface::setUsage(uint32_t reqUsage)
-{
- Mutex::Autolock _l(mSurfaceLock);
- mBufferInfo.set(reqUsage);
-}
-
-int Surface::connect(int api)
-{
- Mutex::Autolock _l(mSurfaceLock);
- int err = NO_ERROR;
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- if (mConnected) {
- err = -EINVAL;
- } else {
- mConnected = api;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-int Surface::disconnect(int api)
-{
- Mutex::Autolock _l(mSurfaceLock);
- int err = NO_ERROR;
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- if (mConnected == api) {
- mConnected = 0;
- } else {
- err = -EINVAL;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-int Surface::crop(Rect const* rect)
-{
- Mutex::Autolock _l(mSurfaceLock);
- // TODO: validate rect size
-
- if (rect == NULL || rect->isEmpty()) {
- mNextBufferCrop = Rect(0,0);
- } else {
- mNextBufferCrop = *rect;
- }
-
- return NO_ERROR;
+ return mSurfaceTextureClient->query(what, value);
}
-int Surface::setBufferCount(int bufferCount)
-{
- sp<ISurface> s(mSurface);
- if (s == 0) return NO_INIT;
-
- class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
- sp<ISurface> surface;
- virtual status_t operator()(int bufferCount) const {
- return surface->setBufferCount(bufferCount);
- }
- public:
- SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { }
- } ipc(s);
-
- status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
- LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
- bufferCount, strerror(-err));
-
- if (err == NO_ERROR) {
- // Clear out any references to the old buffers.
- mBuffers.clear();
- }
-
- return err;
-}
-
-int Surface::setBuffersGeometry(int w, int h, int format)
-{
- if (w<0 || h<0 || format<0)
- return BAD_VALUE;
-
- if ((w && !h) || (!w && h))
- return BAD_VALUE;
-
- Mutex::Autolock _l(mSurfaceLock);
- if (mConnected == NATIVE_WINDOW_API_EGL) {
- return INVALID_OPERATION;
- }
-
- mBufferInfo.set(w, h, format);
- if (format != 0) {
- // we update the format of the surface as reported by query().
- // this is to allow applications to change the format of a surface's
- // buffer, and have it reflected in EGL; which is needed for
- // EGLConfig validation.
- mFormat = format;
- }
-
- mNextBufferCrop = Rect(0,0);
-
- return NO_ERROR;
-}
-
-int Surface::setBuffersTransform(int transform)
-{
- Mutex::Autolock _l(mSurfaceLock);
- mNextBufferTransform = transform;
- return NO_ERROR;
-}
-
-int Surface::setBuffersTimestamp(int64_t timestamp)
-{
- // Surface doesn't really have anything meaningful to do with timestamps
- // so they'll just be dropped here.
- return NO_ERROR;
+int Surface::perform(int operation, va_list args) {
+ return mSurfaceTextureClient->perform(operation, args);
}
// ----------------------------------------------------------------------------
-int Surface::getConnectedApi() const
-{
- Mutex::Autolock _l(mSurfaceLock);
- return mConnected;
+int Surface::getConnectedApi() const {
+ return mSurfaceTextureClient->getConnectedApi();
}
// ----------------------------------------------------------------------------
@@ -967,16 +556,17 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
}
// we're intending to do software rendering from this point
- setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+ mSurfaceTextureClient->setUsage(
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
ANativeWindowBuffer* out;
- status_t err = dequeueBuffer(&out);
+ status_t err = mSurfaceTextureClient->dequeueBuffer(&out);
LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
if (err == NO_ERROR) {
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
- err = lockBuffer(backBuffer.get());
- LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
- getBufferIndex(backBuffer), strerror(-err));
+ err = mSurfaceTextureClient->lockBuffer(backBuffer.get());
+ LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
+ backBuffer->handle, strerror(-err));
if (err == NO_ERROR) {
const Rect bounds(backBuffer->width, backBuffer->height);
const Region boundsRegion(bounds);
@@ -1043,110 +633,14 @@ status_t Surface::unlockAndPost()
status_t err = mLockedBuffer->unlock();
LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
- err = queueBuffer(mLockedBuffer.get());
- LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
- getBufferIndex(mLockedBuffer), strerror(-err));
+ err = mSurfaceTextureClient->queueBuffer(mLockedBuffer.get());
+ LOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
+ mLockedBuffer->handle, strerror(-err));
mPostedBuffer = mLockedBuffer;
mLockedBuffer = 0;
return err;
}
-void Surface::setSwapRectangle(const Rect& r) {
- Mutex::Autolock _l(mSurfaceLock);
- mSwapRectangle = r;
-}
-
-int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
-{
- int idx = buffer->getIndex();
- if (idx < 0) {
- // The buffer doesn't have an index set. See if the handle the same as
- // one of the buffers for which we do know the index. This can happen
- // e.g. if GraphicBuffer is used to wrap an ANativeWindowBuffer that
- // was dequeued from an ANativeWindow.
- for (size_t i = 0; i < mBuffers.size(); i++) {
- if (mBuffers[i] != 0 && buffer->handle == mBuffers[i]->handle) {
- idx = mBuffers[i]->getIndex();
- break;
- }
- }
- }
- return idx;
-}
-
-status_t Surface::getBufferLocked(int index,
- uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
-{
- sp<ISurface> s(mSurface);
- if (s == 0) return NO_INIT;
-
- status_t err = NO_MEMORY;
-
- // free the current buffer
- sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
- if (currentBuffer != 0) {
- currentBuffer.clear();
- }
-
- sp<GraphicBuffer> buffer = s->requestBuffer(index, w, h, format, usage);
- LOGE_IF(buffer==0,
- "ISurface::getBuffer(%d, %08x) returned NULL",
- index, usage);
- if (buffer != 0) { // this should always happen by construction
- LOGE_IF(buffer->handle == NULL,
- "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
- "returned a buffer with a null handle",
- mIdentity, index, w, h, format, usage);
- err = mSharedBufferClient->getStatus();
- LOGE_IF(err, "Surface (identity=%d) state = %d", mIdentity, err);
- if (!err && buffer->handle != NULL) {
- currentBuffer = buffer;
- currentBuffer->setIndex(index);
- } else {
- err = err<0 ? err : status_t(NO_MEMORY);
- }
- }
- return err;
-}
-
-// ----------------------------------------------------------------------------
-Surface::BufferInfo::BufferInfo()
- : mWidth(0), mHeight(0), mFormat(0),
- mUsage(GRALLOC_USAGE_HW_RENDER), mDirty(0)
-{
-}
-
-void Surface::BufferInfo::set(uint32_t w, uint32_t h, uint32_t format) {
- if ((mWidth != w) || (mHeight != h) || (mFormat != format)) {
- mWidth = w;
- mHeight = h;
- mFormat = format;
- mDirty |= GEOMETRY;
- }
-}
-
-void Surface::BufferInfo::set(uint32_t usage) {
- mUsage = usage;
-}
-
-void Surface::BufferInfo::get(uint32_t *pWidth, uint32_t *pHeight,
- uint32_t *pFormat, uint32_t *pUsage) const {
- *pWidth = mWidth;
- *pHeight = mHeight;
- *pFormat = mFormat;
- *pUsage = mUsage;
-}
-
-bool Surface::BufferInfo::validateBuffer(const sp<GraphicBuffer>& buffer) const {
- // make sure we AT LEAST have the usage flags we want
- if (mDirty || buffer==0 ||
- ((buffer->usage & mUsage) != mUsage)) {
- mDirty = 0;
- return false;
- }
- return true;
-}
-
// ----------------------------------------------------------------------------
}; // namespace android