diff options
Diffstat (limited to 'include/private/ui')
-rw-r--r-- | include/private/ui/LayerState.h | 2 | ||||
-rw-r--r-- | include/private/ui/RegionHelper.h | 284 | ||||
-rw-r--r-- | include/private/ui/SharedBufferStack.h | 359 | ||||
-rw-r--r-- | include/private/ui/SharedState.h | 168 | ||||
-rw-r--r-- | include/private/ui/SurfaceFlingerSynchro.h | 76 | ||||
-rw-r--r-- | include/private/ui/android_natives_priv.h | 17 | ||||
-rw-r--r-- | include/private/ui/sw_gralloc_handle.h | 83 |
7 files changed, 743 insertions, 246 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/RegionHelper.h b/include/private/ui/RegionHelper.h new file mode 100644 index 0000000..8d76533 --- /dev/null +++ b/include/private/ui/RegionHelper.h @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2009 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_PRIVATE_REGION_HELPER_H +#define ANDROID_UI_PRIVATE_REGION_HELPER_H + +#include <stdint.h> +#include <sys/types.h> + +namespace android { +// ---------------------------------------------------------------------------- + +template<typename RECT> +class region_operator +{ + typedef typename RECT::value_type TYPE; + static const TYPE max_value = 0x7FFFFFF; + +public: + /* + * Common boolean operations: + * value is computed as 0b101 op 0b110 + * other boolean operation are possible, simply compute + * their corresponding value with the above formulae and use + * it when instantiating a region_operator. + */ + static const uint32_t LHS = 0x5; // 0b101 + static const uint32_t RHS = 0x6; // 0b110 + enum { + op_nand = LHS & ~RHS, + op_and = LHS & RHS, + op_or = LHS | RHS, + op_xor = LHS ^ RHS + }; + + struct region { + RECT const* rects; + size_t count; + TYPE dx; + TYPE dy; + inline region(const region& rhs) + : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { } + inline region(RECT const* r, size_t c) + : rects(r), count(c), dx(), dy() { } + inline region(RECT const* r, size_t c, TYPE dx, TYPE dy) + : rects(r), count(c), dx(dx), dy(dy) { } + }; + + class region_rasterizer { + friend class region_operator; + virtual void operator()(const RECT& rect) = 0; + public: + virtual ~region_rasterizer() { }; + }; + + inline region_operator(int op, const region& lhs, const region& rhs) + : op_mask(op), spanner(lhs, rhs) + { + } + + void operator()(region_rasterizer& rasterizer) { + RECT current; + do { + SpannerInner spannerInner(spanner.lhs, spanner.rhs); + int inside = spanner.next(current.top, current.bottom); + spannerInner.prepare(inside); + do { + TYPE left, right; + int inside = spannerInner.next(current.left, current.right); + if ((op_mask >> inside) & 1) { + if (current.left < current.right && + current.top < current.bottom) { + rasterizer(current); + } + } + } while(!spannerInner.isDone()); + } while(!spanner.isDone()); + } + +private: + uint32_t op_mask; + + class SpannerBase + { + public: + enum { + lhs_before_rhs = 0, + lhs_after_rhs = 1, + lhs_coincide_rhs = 2 + }; + + protected: + TYPE lhs_head; + TYPE lhs_tail; + TYPE rhs_head; + TYPE rhs_tail; + + inline int next(TYPE& head, TYPE& tail, + bool& more_lhs, bool& more_rhs) + { + int inside; + more_lhs = false; + more_rhs = false; + if (lhs_head < rhs_head) { + inside = lhs_before_rhs; + head = lhs_head; + if (lhs_tail <= rhs_head) { + tail = lhs_tail; + more_lhs = true; + } else { + lhs_head = rhs_head; + tail = rhs_head; + } + } else if (rhs_head < lhs_head) { + inside = lhs_after_rhs; + head = rhs_head; + if (rhs_tail <= lhs_head) { + tail = rhs_tail; + more_rhs = true; + } else { + rhs_head = lhs_head; + tail = lhs_head; + } + } else { + inside = lhs_coincide_rhs; + head = lhs_head; + if (lhs_tail <= rhs_tail) { + tail = rhs_head = lhs_tail; + more_lhs = true; + } + if (rhs_tail <= lhs_tail) { + tail = lhs_head = rhs_tail; + more_rhs = true; + } + } + return inside; + } + }; + + class Spanner : protected SpannerBase + { + friend class region_operator; + region lhs; + region rhs; + + public: + inline Spanner(const region& lhs, const region& rhs) + : lhs(lhs), rhs(rhs) + { + SpannerBase::lhs_head = lhs.rects->top + lhs.dy; + SpannerBase::lhs_tail = lhs.rects->bottom + lhs.dy; + SpannerBase::rhs_head = rhs.rects->top + rhs.dy; + SpannerBase::rhs_tail = rhs.rects->bottom + rhs.dy; + } + + inline bool isDone() const { + return !rhs.count && !lhs.count; + } + + inline int next(TYPE& top, TYPE& bottom) + { + bool more_lhs = false; + bool more_rhs = false; + int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs); + if (more_lhs) { + advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail); + } + if (more_rhs) { + advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail); + } + return inside; + } + + private: + static inline + void advance(region& reg, TYPE& aTop, TYPE& aBottom) { + // got to next span + size_t count = reg.count; + RECT const * rects = reg.rects; + RECT const * const end = rects + count; + const int top = rects->top; + while (rects != end && rects->top == top) { + rects++; + count--; + } + if (rects != end) { + aTop = rects->top + reg.dy; + aBottom = rects->bottom + reg.dy; + } else { + aTop = max_value; + aBottom = max_value; + } + reg.rects = rects; + reg.count = count; + } + }; + + class SpannerInner : protected SpannerBase + { + region lhs; + region rhs; + + public: + inline SpannerInner(const region& lhs, const region& rhs) + : lhs(lhs), rhs(rhs) + { + } + + inline void prepare(int inside) { + if (inside == SpannerBase::lhs_before_rhs) { + SpannerBase::lhs_head = lhs.rects->left + lhs.dx; + SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; + SpannerBase::rhs_head = max_value; + SpannerBase::rhs_tail = max_value; + } else if (inside == SpannerBase::lhs_after_rhs) { + SpannerBase::lhs_head = max_value; + SpannerBase::lhs_tail = max_value; + SpannerBase::rhs_head = rhs.rects->left + rhs.dx; + SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; + } else { + SpannerBase::lhs_head = lhs.rects->left + lhs.dx; + SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; + SpannerBase::rhs_head = rhs.rects->left + rhs.dx; + SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; + } + } + + inline bool isDone() const { + return SpannerBase::lhs_head == max_value && + SpannerBase::rhs_head == max_value; + } + + inline int next(TYPE& left, TYPE& right) + { + bool more_lhs = false; + bool more_rhs = false; + int inside = SpannerBase::next(left, right, more_lhs, more_rhs); + if (more_lhs) { + advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail); + } + if (more_rhs) { + advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail); + } + return inside; + } + + private: + static inline + void advance(region& reg, TYPE& left, TYPE& right) { + if (reg.rects && reg.count) { + const int cur_span_top = reg.rects->top; + reg.rects++; + reg.count--; + if (!reg.count || reg.rects->top != cur_span_top) { + left = max_value; + right = max_value; + } else { + left = reg.rects->left + reg.dx; + right = reg.rects->right + reg.dx; + } + } + } + }; + + Spanner spanner; +}; + +// ---------------------------------------------------------------------------- +}; + +#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */ diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h new file mode 100644 index 0000000..bbc1822 --- /dev/null +++ b/include/private/ui/SharedBufferStack.h @@ -0,0 +1,359 @@ +/* + * 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; + +// ---------------------------------------------------------------------------- + +// should be 128 bytes (32 longs) +class SharedBufferStack +{ + friend class SharedClient; + friend class SharedBufferBase; + friend class SharedBufferClient; + friend class SharedBufferServer; + +public: + struct FlatRegion { // 12 bytes + static const unsigned int NUM_RECT_MAX = 1; + uint32_t count; + uint16_t rects[4*NUM_RECT_MAX]; + }; + + struct Statistics { // 4 longs + typedef int32_t usecs_t; + usecs_t totalTime; + usecs_t reserved[3]; + }; + + SharedBufferStack(); + void init(int32_t identity); + 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 + volatile status_t status; // surface's status code + + // not part of the conditions + volatile int32_t reallocMask; + + int32_t identity; // surface's identity (const) + int32_t reserved32[9]; + Statistics stats; + 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; + +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, + int32_t identity); + ~SharedBufferBase(); + uint32_t getIdentity(); + status_t getStatus() const; + size_t getFrontBuffer() const; + String8 dump(char const* prefix) const; + +protected: + SharedClient* const mSharedClient; + SharedBufferStack* const mSharedStack; + const int mNumBuffers; + const int mIdentity; + + 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) +{ + const SharedBufferStack& stack( *mSharedStack ); + SharedClient& client( *mSharedClient ); + const nsecs_t TIMEOUT = s2ns(1); + Mutex::Autolock _l(client.lock); + while ((condition()==false) && + (stack.identity == mIdentity) && + (stack.status == NO_ERROR)) + { + 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(), + stack.identity); + break; + } else { + LOGW("waitForCondition(%s) timed out " + "(identity=%d, status=%d). " + "CPU may be pegged. trying again.", T::name(), + stack.identity, stack.status); + } + } else { + LOGE("waitForCondition(%s) error (%s) ", + T::name(), strerror(-err)); + return err; + } + } + } + return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status; +} + + +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, + int32_t identity); + + 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; + + int32_t computeTail() const; + + 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; + // statistics... + nsecs_t mDequeueTime[NUM_BUFFER_MAX]; +}; + +// ---------------------------------------------------------------------------- + +class SharedBufferServer : public SharedBufferBase +{ +public: + SharedBufferServer(SharedClient* sharedClient, int surface, int num, + int32_t identity); + + ssize_t retireAndLock(); + status_t unlock(int buffer); + void setStatus(status_t status); + status_t reallocate(); + status_t assertReallocate(int buffer); + int32_t getQueuedCount() const; + + Region getDirtyRegion(int buffer) const; + + SharedBufferStack::Statistics getStats() 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 StatusUpdate : public UpdateBase { + const status_t status; + inline StatusUpdate(SharedBufferBase* sbb, status_t status); + 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 546d0ad..0000000 --- a/include/private/ui/SharedState.h +++ /dev/null @@ -1,168 +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/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 - }; - uint16_t w; - uint16_t h; - uint16_t stride; - uint16_t bpr; - uint16_t reserved; - uint8_t format; - uint8_t flags; - ssize_t bits_offset; -}; - -// --------------------------------------------------------------------------- - -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 -{ - Mutex lock; - Condition cv; - layer_cblk_t layers[NUM_LAYERS_MAX] __attribute__((aligned(32))); - - enum { - BLOCKING = 0x00000001, - INSPECT = 0x00000002 - }; - - per_client_cblk_t(); - - // 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 -{ - surface_flinger_cblk_t(); - - uint8_t connected; - uint8_t reserved[3]; - uint32_t pad[7]; - - display_cblk_t displays[NUM_DISPLAY_MAX]; -}; - -// --------------------------------------------------------------------------- - -template<bool> struct CTA; -template<> struct CTA<true> { }; - -// compile-time assertions. just to avoid catastrophes. -inline void compile_time_asserts() { - CTA<sizeof(layer_cblk_t) == 128> sizeof__layer_cblk_t__eq_128; - (void)sizeof__layer_cblk_t__eq_128; // we don't want a warning - CTA<sizeof(per_client_cblk_t) <= 4096> sizeof__per_client_cblk_t__le_4096; - (void)sizeof__per_client_cblk_t__le_4096; // we don't want a warning - CTA<sizeof(surface_flinger_cblk_t) <= 4096> sizeof__surface_flinger_cblk_t__le_4096; - (void)sizeof__surface_flinger_cblk_t__le_4096; // we don't want a warning -} - -}; // namespace android - -#endif // ANDROID_UI_SHARED_STATE_H - diff --git a/include/private/ui/SurfaceFlingerSynchro.h b/include/private/ui/SurfaceFlingerSynchro.h deleted file mode 100644 index ff91b61..0000000 --- a/include/private/ui/SurfaceFlingerSynchro.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2008 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_SURFACE_FLINGER_SYNCHRO_H -#define ANDROID_SURFACE_FLINGER_SYNCHRO_H - -#include <stdint.h> -#include <sys/types.h> -#include <utils/Errors.h> -#include <utils/threads.h> -#include <ui/ISurfaceComposer.h> - -namespace android { - -class SurfaceFlinger; - -class SurfaceFlingerSynchro -{ -public: - - // client constructor - SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger); - ~SurfaceFlingerSynchro(); - - // signal surfaceflinger for some work - status_t signal(); - -private: - class Barrier { - public: - Barrier(); - ~Barrier(); - void open(); - void close(); - void waitAndClose(); - status_t waitAndClose(nsecs_t timeout); - private: - enum { OPENED, CLOSED }; - mutable Mutex lock; - mutable Condition cv; - volatile int state; - }; - - friend class SurfaceFlinger; - - // server constructor - SurfaceFlingerSynchro(); - - void open(); - - // wait until there is some work to do - status_t wait(); - status_t wait(nsecs_t timeout); - - sp<ISurfaceComposer> mSurfaceComposer; - Barrier mBarrier; -}; - -}; // namespace android - -#endif // ANDROID_SURFACE_FLINGER_SYNCHRO_H - diff --git a/include/private/ui/android_natives_priv.h b/include/private/ui/android_natives_priv.h new file mode 100644 index 0000000..6b9f524 --- /dev/null +++ b/include/private/ui/android_natives_priv.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2009 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. + */ + +#include <ui/android_native_buffer.h> diff --git a/include/private/ui/sw_gralloc_handle.h b/include/private/ui/sw_gralloc_handle.h new file mode 100644 index 0000000..b3d333e --- /dev/null +++ b/include/private/ui/sw_gralloc_handle.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 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_PRIVATE_SW_GRALLOC_HANDLE_H +#define ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H + +#include <stdint.h> +#include <limits.h> +#include <sys/cdefs.h> +#include <hardware/gralloc.h> +#include <errno.h> + +#include <cutils/native_handle.h> + +namespace android { + +/*****************************************************************************/ + +struct sw_gralloc_handle_t : public native_handle +{ + // file-descriptors + int fd; + // ints + int magic; + int size; + int base; + int prot; + int pid; + + static const int sNumInts = 5; + static const int sNumFds = 1; + static const int sMagic = '_sgh'; + + sw_gralloc_handle_t() : + fd(-1), magic(sMagic), size(0), base(0), prot(0), pid(getpid()) + { + version = sizeof(native_handle); + numInts = sNumInts; + numFds = sNumFds; + } + ~sw_gralloc_handle_t() { + magic = 0; + } + + static int validate(const native_handle* h) { + const sw_gralloc_handle_t* hnd = (const sw_gralloc_handle_t*)h; + if (!h || h->version != sizeof(native_handle) || + h->numInts != sNumInts || h->numFds != sNumFds || + hnd->magic != sMagic) + { + return -EINVAL; + } + return 0; + } + + static status_t alloc(uint32_t w, uint32_t h, int format, + int usage, buffer_handle_t* handle, int32_t* stride); + static status_t free(sw_gralloc_handle_t* hnd); + static status_t registerBuffer(sw_gralloc_handle_t* hnd); + static status_t unregisterBuffer(sw_gralloc_handle_t* hnd); + static status_t lock(sw_gralloc_handle_t* hnd, int usage, + int l, int t, int w, int h, void** vaddr); + static status_t unlock(sw_gralloc_handle_t* hnd); +}; + +/*****************************************************************************/ + +}; // namespace android + +#endif /* ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H */ |