summaryrefslogtreecommitdiffstats
path: root/include/private/ui
diff options
context:
space:
mode:
Diffstat (limited to 'include/private/ui')
-rw-r--r--include/private/ui/LayerState.h2
-rw-r--r--include/private/ui/SharedBufferStack.h327
-rw-r--r--include/private/ui/SharedState.h154
-rw-r--r--include/private/ui/SurfaceBuffer.h4
4 files changed, 331 insertions, 156 deletions
diff --git a/include/private/ui/LayerState.h b/include/private/ui/LayerState.h
index b6fcd80..f1a2618 100644
--- a/include/private/ui/LayerState.h
+++ b/include/private/ui/LayerState.h
@@ -25,8 +25,6 @@
#include <ui/ISurfaceFlingerClient.h>
#include <ui/Region.h>
-#include <private/ui/SharedState.h>
-
namespace android {
class Parcel;
diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h
new file mode 100644
index 0000000..2bd5344
--- /dev/null
+++ b/include/private/ui/SharedBufferStack.h
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2007 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_UI_SHARED_BUFFER_STACK_H
+#define ANDROID_UI_SHARED_BUFFER_STACK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/compiler.h>
+
+#include <utils/Debug.h>
+#include <utils/threads.h>
+#include <utils/String8.h>
+
+#include <ui/Rect.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+/*
+ * These classes manage a stack of buffers in shared memory.
+ *
+ * SharedClient: represents a client with several stacks
+ * SharedBufferStack: represents a stack of buffers
+ * SharedBufferClient: manipulates the SharedBufferStack from the client side
+ * SharedBufferServer: manipulates the SharedBufferStack from the server side
+ *
+ * Buffers can be dequeued until there are none available, they can be locked
+ * unless they are in use by the server, which is only the case for the last
+ * dequeue-able buffer. When these various conditions are not met, the caller
+ * waits until the condition is met.
+ *
+ *
+ * CAVEATS:
+ *
+ * In the current implementation there are several limitations:
+ * - buffers must be locked in the same order they've been dequeued
+ * - buffers must be enqueued in the same order they've been locked
+ * - dequeue() is not reentrant
+ * - no error checks are done on the condition above
+ *
+ */
+
+// When changing these values, the COMPILE_TIME_ASSERT at the end of this
+// file need to be updated.
+const unsigned int NUM_LAYERS_MAX = 31;
+const unsigned int NUM_BUFFER_MAX = 4;
+const unsigned int NUM_DISPLAY_MAX = 4;
+
+// ----------------------------------------------------------------------------
+
+class Region;
+class SharedBufferStack;
+class SharedClient;
+
+// ----------------------------------------------------------------------------
+
+struct FlatRegion { // 12 bytes
+ static const unsigned int NUM_RECT_MAX = 1;
+ uint32_t count;
+ uint16_t rects[4*NUM_RECT_MAX];
+};
+
+// should be 128 bytes (32 longs)
+class SharedBufferStack
+{
+ friend class SharedClient;
+ friend class SharedBufferBase;
+ friend class SharedBufferClient;
+ friend class SharedBufferServer;
+
+public:
+ SharedBufferStack();
+ status_t setDirtyRegion(int buffer, const Region& reg);
+ Region getDirtyRegion(int buffer) const;
+
+ // these attributes are part of the conditions/updates
+ volatile int32_t head; // server's current front buffer
+ volatile int32_t available; // number of dequeue-able buffers
+ volatile int32_t queued; // number of buffers waiting for post
+ volatile int32_t inUse; // buffer currently in use by SF
+
+ // not part of the conditions
+ volatile int32_t reallocMask;
+
+ int32_t identity; // surface's identity (const)
+ status_t status; // surface's status code
+ int32_t reserved32[13];
+ FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 12*4=48 bytes
+};
+
+// ----------------------------------------------------------------------------
+
+// 4 KB max
+class SharedClient
+{
+public:
+ SharedClient();
+ ~SharedClient();
+
+ status_t validate(size_t token) const;
+ uint32_t getIdentity(size_t token) const;
+ status_t setIdentity(size_t token, uint32_t identity);
+
+private:
+ friend class SharedBufferBase;
+ friend class SharedBufferClient;
+ friend class SharedBufferServer;
+
+ // FIXME: this should be replaced by a lock-less primitive
+ Mutex lock;
+ Condition cv;
+ SharedBufferStack surfaces[ NUM_LAYERS_MAX ];
+};
+
+// ============================================================================
+
+class SharedBufferBase
+{
+public:
+ SharedBufferBase(SharedClient* sharedClient, int surface, int num);
+ ~SharedBufferBase();
+ uint32_t getIdentity();
+ size_t getFrontBuffer() const;
+ String8 dump(char const* prefix) const;
+
+protected:
+ SharedClient* const mSharedClient;
+ SharedBufferStack* const mSharedStack;
+ const int mNumBuffers;
+
+ friend struct Update;
+ friend struct QueueUpdate;
+
+ struct ConditionBase {
+ SharedBufferStack& stack;
+ inline ConditionBase(SharedBufferBase* sbc)
+ : stack(*sbc->mSharedStack) { }
+ };
+
+ struct UpdateBase {
+ SharedBufferStack& stack;
+ inline UpdateBase(SharedBufferBase* sbb)
+ : stack(*sbb->mSharedStack) { }
+ };
+
+ template <typename T>
+ status_t waitForCondition(T condition);
+
+ template <typename T>
+ status_t updateCondition(T update);
+};
+
+template <typename T>
+status_t SharedBufferBase::waitForCondition(T condition)
+{
+ SharedClient& client( *mSharedClient );
+ const nsecs_t TIMEOUT = s2ns(1);
+ Mutex::Autolock _l(client.lock);
+ while (!condition()) {
+ status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
+
+ // handle errors and timeouts
+ if (CC_UNLIKELY(err != NO_ERROR)) {
+ if (err == TIMED_OUT) {
+ if (condition()) {
+ LOGE("waitForCondition(%s) timed out (identity=%d), "
+ "but condition is true! We recovered but it "
+ "shouldn't happen." ,
+ T::name(), mSharedStack->identity);
+ break;
+ } else {
+ LOGW("waitForCondition(%s) timed out (identity=%d). "
+ "CPU may be pegged. trying again.",
+ T::name(), mSharedStack->identity);
+ }
+ } else {
+ LOGE("waitForCondition(%s) error (%s) ",
+ T::name(), strerror(-err));
+ return err;
+ }
+ }
+ }
+ return NO_ERROR;
+}
+
+
+template <typename T>
+status_t SharedBufferBase::updateCondition(T update) {
+ SharedClient& client( *mSharedClient );
+ Mutex::Autolock _l(client.lock);
+ ssize_t result = update();
+ client.cv.broadcast();
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+
+class SharedBufferClient : public SharedBufferBase
+{
+public:
+ SharedBufferClient(SharedClient* sharedClient, int surface, int num);
+
+ ssize_t dequeue();
+ status_t undoDequeue(int buf);
+
+ status_t lock(int buf);
+ status_t queue(int buf);
+ bool needNewBuffer(int buffer) const;
+ status_t setDirtyRegion(int buffer, const Region& reg);
+
+private:
+ friend struct Condition;
+ friend struct DequeueCondition;
+ friend struct LockCondition;
+
+ struct QueueUpdate : public UpdateBase {
+ inline QueueUpdate(SharedBufferBase* sbb);
+ inline ssize_t operator()();
+ };
+
+ struct UndoDequeueUpdate : public UpdateBase {
+ inline UndoDequeueUpdate(SharedBufferBase* sbb);
+ inline ssize_t operator()();
+ };
+
+ // --
+
+ struct DequeueCondition : public ConditionBase {
+ inline DequeueCondition(SharedBufferClient* sbc);
+ inline bool operator()();
+ static inline const char* name() { return "DequeueCondition"; }
+ };
+
+ struct LockCondition : public ConditionBase {
+ int buf;
+ inline LockCondition(SharedBufferClient* sbc, int buf);
+ inline bool operator()();
+ static inline const char* name() { return "LockCondition"; }
+ };
+
+ int32_t tail;
+};
+
+// ----------------------------------------------------------------------------
+
+class SharedBufferServer : public SharedBufferBase
+{
+public:
+ SharedBufferServer(SharedClient* sharedClient, int surface, int num);
+
+ ssize_t retireAndLock();
+ status_t unlock(int buffer);
+ status_t reallocate();
+ status_t assertReallocate(int buffer);
+
+ Region getDirtyRegion(int buffer) const;
+
+private:
+ struct UnlockUpdate : public UpdateBase {
+ const int lockedBuffer;
+ inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
+ inline ssize_t operator()();
+ };
+
+ struct RetireUpdate : public UpdateBase {
+ const int numBuffers;
+ inline RetireUpdate(SharedBufferBase* sbb, int numBuffers);
+ inline ssize_t operator()();
+ };
+
+ struct ReallocateCondition : public ConditionBase {
+ int buf;
+ inline ReallocateCondition(SharedBufferBase* sbb, int buf);
+ inline bool operator()();
+ static inline const char* name() { return "ReallocateCondition"; }
+ };
+};
+
+// ===========================================================================
+
+struct display_cblk_t
+{
+ uint16_t w;
+ uint16_t h;
+ uint8_t format;
+ uint8_t orientation;
+ uint8_t reserved[2];
+ float fps;
+ float density;
+ float xdpi;
+ float ydpi;
+ uint32_t pad[2];
+};
+
+struct surface_flinger_cblk_t // 4KB max
+{
+ uint8_t connected;
+ uint8_t reserved[3];
+ uint32_t pad[7];
+ display_cblk_t displays[NUM_DISPLAY_MAX];
+};
+
+// ---------------------------------------------------------------------------
+
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096)
+COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128)
+COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif /* ANDROID_UI_SHARED_BUFFER_STACK_H */
diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h
deleted file mode 100644
index c9f6b5e..0000000
--- a/include/private/ui/SharedState.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2007 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_UI_SHARED_STATE_H
-#define ANDROID_UI_SHARED_STATE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Debug.h>
-#include <utils/threads.h>
-
-namespace android {
-
-/*
- * These structures are shared between the composer process and its clients
- */
-
-// ---------------------------------------------------------------------------
-
-struct surface_info_t { // 4 longs, 16 bytes
- enum {
- eBufferDirty = 0x01,
- eNeedNewBuffer = 0x02
- };
- uint8_t reserved[11];
- uint8_t flags;
- status_t status;
-};
-
-// ---------------------------------------------------------------------------
-
-const uint32_t NUM_LAYERS_MAX = 31;
-
-enum { // layer_cblk_t swapState
- eIndex = 0x00000001,
- eFlipRequested = 0x00000002,
-
- eResizeBuffer0 = 0x00000004,
- eResizeBuffer1 = 0x00000008,
- eResizeRequested = eResizeBuffer0 | eResizeBuffer1,
-
- eBusy = 0x00000010,
- eLocked = 0x00000020,
- eNextFlipPending = 0x00000040,
- eInvalidSurface = 0x00000080
-};
-
-enum { // layer_cblk_t flags
- eLayerNotPosted = 0x00000001,
- eNoCopyBack = 0x00000002,
- eReserved = 0x0000007C,
- eBufferIndexShift = 7,
- eBufferIndex = 1<<eBufferIndexShift,
-};
-
-struct flat_region_t // 40 bytes
-{
- int32_t count;
- int16_t l;
- int16_t t;
- int16_t r;
- int16_t b;
- uint16_t runs[14];
-};
-
-struct layer_cblk_t // (128 bytes)
-{
- volatile int32_t swapState; // 4
- volatile int32_t flags; // 4
- volatile int32_t identity; // 4
- int32_t reserved; // 4
- surface_info_t surface[2]; // 32
- flat_region_t region[2]; // 80
-
- static inline int backBuffer(uint32_t state) {
- return ((state & eIndex) ^ ((state & eFlipRequested)>>1));
- }
- static inline int frontBuffer(uint32_t state) {
- return 1 - backBuffer(state);
- }
-};
-
-// ---------------------------------------------------------------------------
-
-struct per_client_cblk_t // 4KB max
-{
- per_client_cblk_t() : lock(Mutex::SHARED) { }
-
- Mutex lock;
- Condition cv;
- layer_cblk_t layers[NUM_LAYERS_MAX] __attribute__((aligned(32)));
-
- enum {
- BLOCKING = 0x00000001,
- INSPECT = 0x00000002
- };
-
- // these functions are used by the clients
- status_t validate(size_t i) const;
- int32_t lock_layer(size_t i, uint32_t flags);
- uint32_t unlock_layer_and_post(size_t i);
- void unlock_layer(size_t i);
-};
-// ---------------------------------------------------------------------------
-
-const uint32_t NUM_DISPLAY_MAX = 4;
-
-struct display_cblk_t
-{
- uint16_t w;
- uint16_t h;
- uint8_t format;
- uint8_t orientation;
- uint8_t reserved[2];
- float fps;
- float density;
- float xdpi;
- float ydpi;
- uint32_t pad[2];
-};
-
-struct surface_flinger_cblk_t // 4KB max
-{
- uint8_t connected;
- uint8_t reserved[3];
- uint32_t pad[7];
- display_cblk_t displays[NUM_DISPLAY_MAX];
-};
-
-// ---------------------------------------------------------------------------
-
-COMPILE_TIME_ASSERT(sizeof(layer_cblk_t) == 128)
-COMPILE_TIME_ASSERT(sizeof(per_client_cblk_t) <= 4096)
-COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_UI_SHARED_STATE_H
-
diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h
index bf68406..73e517b 100644
--- a/include/private/ui/SurfaceBuffer.h
+++ b/include/private/ui/SurfaceBuffer.h
@@ -47,6 +47,9 @@ public:
status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
status_t unlock();
+ void setIndex(int index);
+ int getIndex() const;
+
protected:
SurfaceBuffer();
SurfaceBuffer(const Parcel& reply);
@@ -69,6 +72,7 @@ private:
android_native_buffer_t const* buffer);
BufferMapper& mBufferMapper;
+ int mIndex;
};
}; // namespace android