summaryrefslogtreecommitdiffstats
path: root/libs/ui
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ui')
-rw-r--r--libs/ui/Android.mk6
-rw-r--r--libs/ui/Fence.cpp106
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp71
-rw-r--r--libs/ui/Region.cpp74
4 files changed, 182 insertions, 75 deletions
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 5aff7a4..80c28a1 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -16,6 +16,7 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
+ Fence.cpp \
FramebufferNativeWindow.cpp \
GraphicBuffer.cpp \
GraphicBufferAllocator.cpp \
@@ -26,8 +27,9 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libcutils \
- libutils \
- libhardware
+ libhardware \
+ libsync \
+ libutils
ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),)
LOCAL_CFLAGS += -DFRAMEBUFFER_FORCE_FORMAT=$(BOARD_FRAMEBUFFER_FORCE_FORMAT)
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
new file mode 100644
index 0000000..cec5876
--- /dev/null
+++ b/libs/ui/Fence.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#define LOG_TAG "Fence"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+//#define LOG_NDEBUG 0
+
+#include <sync/sync.h>
+#include <ui/Fence.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+namespace android {
+
+const sp<Fence> Fence::NO_FENCE = sp<Fence>();
+
+Fence::Fence() :
+ mFenceFd(-1) {
+}
+
+Fence::Fence(int fenceFd) :
+ mFenceFd(fenceFd) {
+}
+
+Fence::~Fence() {
+ if (mFenceFd != -1) {
+ close(mFenceFd);
+ }
+}
+
+int Fence::wait(unsigned int timeout) {
+ ATRACE_CALL();
+ if (mFenceFd == -1) {
+ return NO_ERROR;
+ }
+ return sync_wait(mFenceFd, timeout);
+}
+
+sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
+ const sp<Fence>& f2) {
+ ATRACE_CALL();
+ int result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
+ if (result == -1) {
+ status_t err = -errno;
+ ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
+ name.string(), f1->mFenceFd, f2->mFenceFd,
+ strerror(-err), err);
+ return NO_FENCE;
+ }
+ return sp<Fence>(new Fence(result));
+}
+
+int Fence::dup() const {
+ if (mFenceFd == -1) {
+ return -1;
+ }
+ return ::dup(mFenceFd);
+}
+
+size_t Fence::getFlattenedSize() const {
+ return 0;
+}
+
+size_t Fence::getFdCount() const {
+ return 1;
+}
+
+status_t Fence::flatten(void* buffer, size_t size, int fds[],
+ size_t count) const {
+ if (size != 0 || count != 1) {
+ return BAD_VALUE;
+ }
+
+ fds[0] = mFenceFd;
+ return NO_ERROR;
+}
+
+status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
+ size_t count) {
+ if (size != 0 || count != 1) {
+ return BAD_VALUE;
+ }
+ if (mFenceFd != -1) {
+ // Don't unflatten if we already have a valid fd.
+ return INVALID_OPERATION;
+ }
+
+ mFenceFd = fds[0];
+ return NO_ERROR;
+}
+
+} // namespace android
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index dec99b6..31a69b2 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -28,6 +28,7 @@
#include <utils/RefBase.h>
#include <ui/ANativeObjectBase.h>
+#include <ui/Fence.h>
#include <ui/FramebufferNativeWindow.h>
#include <ui/Rect.h>
@@ -92,8 +93,13 @@ FramebufferNativeWindow::FramebufferNativeWindow()
mUpdateOnDemand = (fbDev->setUpdateRect != 0);
// initialize the buffer FIFO
- mNumBuffers = NUM_FRAME_BUFFERS;
- mNumFreeBuffers = NUM_FRAME_BUFFERS;
+ if(fbDev->numFramebuffers >= MIN_NUM_FRAME_BUFFERS &&
+ fbDev->numFramebuffers <= MAX_NUM_FRAME_BUFFERS){
+ mNumBuffers = fbDev->numFramebuffers;
+ } else {
+ mNumBuffers = MIN_NUM_FRAME_BUFFERS;
+ }
+ mNumFreeBuffers = mNumBuffers;
mBufferHead = mNumBuffers-1;
/*
@@ -145,19 +151,23 @@ FramebufferNativeWindow::FramebufferNativeWindow()
ANativeWindow::setSwapInterval = setSwapInterval;
ANativeWindow::dequeueBuffer = dequeueBuffer;
- ANativeWindow::lockBuffer = lockBuffer;
ANativeWindow::queueBuffer = queueBuffer;
ANativeWindow::query = query;
ANativeWindow::perform = perform;
+
+ ANativeWindow::dequeueBuffer_DEPRECATED = dequeueBuffer_DEPRECATED;
+ ANativeWindow::lockBuffer_DEPRECATED = lockBuffer_DEPRECATED;
+ ANativeWindow::queueBuffer_DEPRECATED = queueBuffer_DEPRECATED;
}
FramebufferNativeWindow::~FramebufferNativeWindow()
{
if (grDev) {
- if (buffers[0] != NULL)
- grDev->free(grDev, buffers[0]->handle);
- if (buffers[1] != NULL)
- grDev->free(grDev, buffers[1]->handle);
+ for(int i = 0; i < mNumBuffers; i++) {
+ if (buffers[i] != NULL) {
+ grDev->free(grDev, buffers[i]->handle);
+ }
+ }
gralloc_close(grDev);
}
@@ -207,9 +217,24 @@ int FramebufferNativeWindow::getCurrentBufferIndex() const
return index;
}
-int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
+int FramebufferNativeWindow::dequeueBuffer_DEPRECATED(ANativeWindow* window,
ANativeWindowBuffer** buffer)
{
+ int fenceFd = -1;
+ int result = dequeueBuffer(window, buffer, &fenceFd);
+ sp<Fence> fence(new Fence(fenceFd));
+ int waitResult = fence->wait(Fence::TIMEOUT_NEVER);
+ if (waitResult != OK) {
+ ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an "
+ "error: %d", waitResult);
+ return waitResult;
+ }
+ return result;
+}
+
+int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
+ ANativeWindowBuffer** buffer, int* fenceFd)
+{
FramebufferNativeWindow* self = getSelf(window);
Mutex::Autolock _l(self->mutex);
framebuffer_device_t* fb = self->fbDev;
@@ -218,43 +243,45 @@ int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
if (self->mBufferHead >= self->mNumBuffers)
self->mBufferHead = 0;
- // wait for a free buffer
- while (!self->mNumFreeBuffers) {
+ // wait for a free non-front buffer
+ while (self->mNumFreeBuffers < 2) {
self->mCondition.wait(self->mutex);
}
+ ALOG_ASSERT(self->buffers[index] != self->front);
+
// get this buffer
self->mNumFreeBuffers--;
self->mCurrentBufferIndex = index;
*buffer = self->buffers[index].get();
+ *fenceFd = -1;
return 0;
}
-int FramebufferNativeWindow::lockBuffer(ANativeWindow* window,
+int FramebufferNativeWindow::lockBuffer_DEPRECATED(ANativeWindow* window,
ANativeWindowBuffer* buffer)
{
- FramebufferNativeWindow* self = getSelf(window);
- Mutex::Autolock _l(self->mutex);
-
- const int index = self->mCurrentBufferIndex;
-
- // wait that the buffer we're locking is not front anymore
- while (self->front == buffer) {
- self->mCondition.wait(self->mutex);
- }
-
return NO_ERROR;
}
-int FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
+int FramebufferNativeWindow::queueBuffer_DEPRECATED(ANativeWindow* window,
ANativeWindowBuffer* buffer)
{
+ return queueBuffer(window, buffer, -1);
+}
+
+int FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
+ ANativeWindowBuffer* buffer, int fenceFd)
+{
FramebufferNativeWindow* self = getSelf(window);
Mutex::Autolock _l(self->mutex);
framebuffer_device_t* fb = self->fbDev;
buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
+ sp<Fence> fence(new Fence(fenceFd));
+ fence->wait(Fence::TIMEOUT_NEVER);
+
const int index = self->mCurrentBufferIndex;
int res = fb->post(fb, handle);
self->front = static_cast<NativeBuffer*>(buffer);
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 2c7cdf0..a3d8b01 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -66,12 +66,6 @@ Region::Region(const Rect& rhs)
{
}
-Region::Region(const void* buffer)
-{
- status_t err = read(buffer);
- ALOGE_IF(err<0, "error %s reading Region from buffer", strerror(err));
-}
-
Region::~Region()
{
}
@@ -561,55 +555,33 @@ void Region::translate(Region& dst, const Region& reg, int dx, int dy)
// ----------------------------------------------------------------------------
-ssize_t Region::write(void* buffer, size_t size) const
-{
-#if VALIDATE_REGIONS
- validate(*this, "write(buffer)");
-#endif
- const size_t count = mStorage.size();
- const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
- if (buffer != NULL) {
- if (sizeNeeded > size) return NO_MEMORY;
- int32_t* const p = static_cast<int32_t*>(buffer);
- *p = count;
- memcpy(p+1, &mBounds, sizeof(Rect));
- if (count) {
- memcpy(p+5, mStorage.array(), count*sizeof(Rect));
- }
- }
- return ssize_t(sizeNeeded);
+size_t Region::getSize() const {
+ return (mStorage.size() + 1) * sizeof(Rect);
}
-ssize_t Region::read(const void* buffer)
-{
- int32_t const* const p = static_cast<int32_t const*>(buffer);
- const size_t count = *p;
- memcpy(&mBounds, p+1, sizeof(Rect));
- mStorage.clear();
- if (count) {
- mStorage.insertAt(0, count);
- memcpy(mStorage.editArray(), p+5, count*sizeof(Rect));
- }
-#if VALIDATE_REGIONS
- validate(*this, "read(buffer)");
-#endif
- return ssize_t(sizeof(int32_t) + (1+count)*sizeof(Rect));
-}
-
-ssize_t Region::writeEmpty(void* buffer, size_t size)
-{
- const size_t sizeNeeded = sizeof(int32_t) + sizeof(Rect);
- if (sizeNeeded > size) return NO_MEMORY;
- int32_t* const p = static_cast<int32_t*>(buffer);
- memset(p, 0, sizeNeeded);
- return ssize_t(sizeNeeded);
+status_t Region::flatten(void* buffer) const {
+ Rect* rects = reinterpret_cast<Rect*>(buffer);
+ *rects++ = mBounds;
+ memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
+ return NO_ERROR;
}
-bool Region::isEmpty(void* buffer)
-{
- int32_t const* const p = static_cast<int32_t const*>(buffer);
- Rect const* const b = reinterpret_cast<Rect const *>(p+1);
- return b->isEmpty();
+status_t Region::unflatten(void const* buffer, size_t size) {
+ mStorage.clear();
+ if (size >= sizeof(Rect)) {
+ Rect const* rects = reinterpret_cast<Rect const*>(buffer);
+ mBounds = *rects++;
+ size -= sizeof(Rect);
+ size_t count = size / sizeof(Rect);
+ if (count > 0) {
+ ssize_t err = mStorage.insertAt(0, count);
+ if (err < 0) {
+ return status_t(err);
+ }
+ memcpy(mStorage.editArray(), rects, count*sizeof(Rect));
+ }
+ }
+ return NO_ERROR;
}
// ----------------------------------------------------------------------------