summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/private/surfaceflinger/SharedBufferStack.h202
-rw-r--r--include/surfaceflinger/ISurface.h19
-rw-r--r--include/surfaceflinger/ISurfaceComposer.h4
-rw-r--r--include/surfaceflinger/ISurfaceComposerClient.h (renamed from include/surfaceflinger/ISurfaceFlingerClient.h)31
-rw-r--r--include/surfaceflinger/Surface.h108
-rw-r--r--include/surfaceflinger/SurfaceComposerClient.h56
-rw-r--r--include/ui/GraphicBufferAllocator.h2
-rw-r--r--include/ui/android_native_buffer.h9
-rw-r--r--include/ui/egl/android_natives.h103
-rw-r--r--include/utils/ResourceTypes.h31
-rw-r--r--include/utils/Singleton.h8
-rw-r--r--include/utils/ZipFileCRO.h4
-rw-r--r--include/utils/ZipFileRO.h33
-rw-r--r--include/utils/threads.h90
14 files changed, 522 insertions, 178 deletions
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 9b5a1e0..dcce25e 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -55,12 +55,6 @@ namespace android {
*
*/
-// 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;
@@ -69,7 +63,11 @@ class SharedClient;
// ----------------------------------------------------------------------------
-// should be 128 bytes (32 longs)
+// 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX
+// 4 * (11 + 7 + (1 + 2*7)*16) * 31
+// 1032 * 31
+// = ~27 KiB (31992)
+
class SharedBufferStack
{
friend class SharedClient;
@@ -78,21 +76,38 @@ class SharedBufferStack
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];
- };
-
+ // When changing these values, the COMPILE_TIME_ASSERT at the end of this
+ // file need to be updated.
+ static const unsigned int NUM_LAYERS_MAX = 31;
+ static const unsigned int NUM_BUFFER_MAX = 16;
+ static const unsigned int NUM_BUFFER_MIN = 2;
+ static const unsigned int NUM_DISPLAY_MAX = 4;
+
struct Statistics { // 4 longs
typedef int32_t usecs_t;
usecs_t totalTime;
usecs_t reserved[3];
};
+
+ struct SmallRect {
+ uint16_t l, t, r, b;
+ };
+
+ struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
+ static const unsigned int NUM_RECT_MAX = 6;
+ uint32_t count;
+ SmallRect rects[NUM_RECT_MAX];
+ };
+
+ struct BufferData {
+ FlatRegion dirtyRegion;
+ SmallRect crop;
+ };
SharedBufferStack();
void init(int32_t identity);
status_t setDirtyRegion(int buffer, const Region& reg);
+ status_t setCrop(int buffer, const Rect& reg);
Region getDirtyRegion(int buffer) const;
// these attributes are part of the conditions/updates
@@ -104,24 +119,24 @@ public:
// not part of the conditions
volatile int32_t reallocMask;
+ volatile int8_t index[NUM_BUFFER_MAX];
int32_t identity; // surface's identity (const)
- int32_t reserved32[9];
+ int32_t reserved32[2];
Statistics stats;
- FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 12*4=48 bytes
+ int32_t reserved;
+ BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes
};
// ----------------------------------------------------------------------------
-// 4 KB max
+// 32 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;
@@ -131,7 +146,7 @@ private:
// FIXME: this should be replaced by a lock-less primitive
Mutex lock;
Condition cv;
- SharedBufferStack surfaces[ NUM_LAYERS_MAX ];
+ SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
};
// ============================================================================
@@ -139,18 +154,17 @@ private:
class SharedBufferBase
{
public:
- SharedBufferBase(SharedClient* sharedClient, int surface, int num,
+ SharedBufferBase(SharedClient* sharedClient, int surface,
int32_t identity);
~SharedBufferBase();
- uint32_t getIdentity();
status_t getStatus() const;
+ int32_t getIdentity() 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;
@@ -160,61 +174,22 @@ protected:
SharedBufferStack& stack;
inline ConditionBase(SharedBufferBase* sbc)
: stack(*sbc->mSharedStack) { }
+ virtual ~ConditionBase() { };
+ virtual bool operator()() const = 0;
+ virtual const char* name() const = 0;
};
+ status_t waitForCondition(const ConditionBase& condition);
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);
@@ -238,13 +213,21 @@ public:
status_t queue(int buf);
bool needNewBuffer(int buffer) const;
status_t setDirtyRegion(int buffer, const Region& reg);
+ status_t setCrop(int buffer, const Rect& reg);
+
+ class SetBufferCountCallback {
+ friend class SharedBufferClient;
+ virtual status_t operator()(int bufferCount) const = 0;
+ protected:
+ virtual ~SetBufferCountCallback() { }
+ };
+ status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc);
+
private:
friend struct Condition;
friend struct DequeueCondition;
friend struct LockCondition;
-
- int32_t computeTail() const;
struct QueueUpdate : public UpdateBase {
inline QueueUpdate(SharedBufferBase* sbb);
@@ -260,20 +243,27 @@ private:
struct DequeueCondition : public ConditionBase {
inline DequeueCondition(SharedBufferClient* sbc);
- inline bool operator()();
- static inline const char* name() { return "DequeueCondition"; }
+ inline bool operator()() const;
+ inline const char* name() const { return "DequeueCondition"; }
};
struct LockCondition : public ConditionBase {
int buf;
inline LockCondition(SharedBufferClient* sbc, int buf);
- inline bool operator()();
- static inline const char* name() { return "LockCondition"; }
+ inline bool operator()() const;
+ inline const char* name() const { return "LockCondition"; }
};
+ int32_t computeTail() const;
+
+ mutable RWLock mLock;
+ int mNumBuffers;
+
int32_t tail;
+ int32_t undoDequeueTail;
+ int32_t queued_head;
// statistics...
- nsecs_t mDequeueTime[NUM_BUFFER_MAX];
+ nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
};
// ----------------------------------------------------------------------------
@@ -287,16 +277,71 @@ public:
ssize_t retireAndLock();
status_t unlock(int buffer);
void setStatus(status_t status);
- status_t reallocate();
+ status_t reallocateAll();
+ status_t reallocateAllExcept(int buffer);
status_t assertReallocate(int buffer);
int32_t getQueuedCount() const;
-
Region getDirtyRegion(int buffer) const;
+ status_t resize(int newNumBuffers);
+
SharedBufferStack::Statistics getStats() const;
private:
+ /*
+ * BufferList is basically a fixed-capacity sorted-vector of
+ * unsigned 5-bits ints using a 32-bits int as storage.
+ * it has efficient iterators to find items in the list and not in the list.
+ */
+ class BufferList {
+ size_t mCapacity;
+ uint32_t mList;
+ public:
+ BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX)
+ : mCapacity(c), mList(0) { }
+ status_t add(int value);
+ status_t remove(int value);
+ uint32_t getMask() const { return mList; }
+
+ class const_iterator {
+ friend class BufferList;
+ uint32_t mask, curr;
+ const_iterator(uint32_t mask) :
+ mask(mask), curr(__builtin_clz(mask)) {
+ }
+ public:
+ inline bool operator == (const const_iterator& rhs) const {
+ return mask == rhs.mask;
+ }
+ inline bool operator != (const const_iterator& rhs) const {
+ return mask != rhs.mask;
+ }
+ inline int operator *() const { return curr; }
+ inline const const_iterator& operator ++() {
+ mask &= ~(1<<(31-curr));
+ curr = __builtin_clz(mask);
+ return *this;
+ }
+ };
+
+ inline const_iterator begin() const {
+ return const_iterator(mList);
+ }
+ inline const_iterator end() const {
+ return const_iterator(0);
+ }
+ inline const_iterator free_begin() const {
+ uint32_t mask = (1 << (32-mCapacity)) - 1;
+ return const_iterator( ~(mList | mask) );
+ }
+ };
+
+ // this protects mNumBuffers and mBufferList
+ mutable RWLock mLock;
+ int mNumBuffers;
+ BufferList mBufferList;
+
struct UnlockUpdate : public UpdateBase {
const int lockedBuffer;
inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
@@ -318,8 +363,8 @@ private:
struct ReallocateCondition : public ConditionBase {
int buf;
inline ReallocateCondition(SharedBufferBase* sbb, int buf);
- inline bool operator()();
- static inline const char* name() { return "ReallocateCondition"; }
+ inline bool operator()() const;
+ inline const char* name() const { return "ReallocateCondition"; }
};
};
@@ -344,13 +389,12 @@ 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];
+ display_cblk_t displays[SharedBufferStack::NUM_DISPLAY_MAX];
};
// ---------------------------------------------------------------------------
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096)
-COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128)
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
// ---------------------------------------------------------------------------
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index 472f759..ddbe03d 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -47,13 +47,30 @@ protected:
POST_BUFFER, // one-way transaction
CREATE_OVERLAY,
REQUEST_BUFFER,
+ SET_BUFFER_COUNT,
};
public:
DECLARE_META_INTERFACE(Surface);
- virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0;
+ /*
+ * requests a new buffer for the given index. If w, h, or format are
+ * null the buffer is created with the parameters assigned to the
+ * surface it is bound to. Otherwise the buffer's parameters are
+ * set to those specified.
+ */
+ virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+ uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0;
+
+ /*
+ * sets the number of buffers dequeuable for this surface.
+ */
+ virtual status_t setBufferCount(int bufferCount) = 0;
+ // ------------------------------------------------------------------------
+ // Deprecated...
+ // ------------------------------------------------------------------------
+
class BufferHeap {
public:
enum {
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index d1e7785..3271cfd 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -27,7 +27,7 @@
#include <ui/PixelFormat.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
namespace android {
// ----------------------------------------------------------------------------
@@ -86,7 +86,7 @@ public:
* ACCESS_SURFACE_FLINGER permission
*/
- virtual sp<ISurfaceFlingerClient> createConnection() = 0;
+ virtual sp<ISurfaceComposerClient> createConnection() = 0;
/* retrieve the control block */
virtual sp<IMemoryHeap> getCblk() const = 0;
diff --git a/include/surfaceflinger/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h
index d257645..b2a4766 100644
--- a/include/surfaceflinger/ISurfaceFlingerClient.h
+++ b/include/surfaceflinger/ISurfaceComposerClient.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
-#define ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
+#ifndef ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#define ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
#include <stdint.h>
#include <sys/types.h>
@@ -26,7 +26,7 @@
#include <binder/IInterface.h>
#include <ui/PixelFormat.h>
-
+
#include <surfaceflinger/ISurface.h>
namespace android {
@@ -42,10 +42,10 @@ typedef int32_t DisplayID;
class layer_state_t;
-class ISurfaceFlingerClient : public IInterface
+class ISurfaceComposerClient : public IInterface
{
-public:
- DECLARE_META_INTERFACE(SurfaceFlingerClient);
+public:
+ DECLARE_META_INTERFACE(SurfaceComposerClient);
struct surface_data_t {
int32_t token;
@@ -56,26 +56,35 @@ public:
status_t readFromParcel(const Parcel& parcel);
status_t writeToParcel(Parcel* parcel) const;
};
-
+
virtual sp<IMemoryHeap> getControlBlock() const = 0;
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
virtual sp<ISurface> createSurface( surface_data_t* data,
- int pid,
+ int pid,
const String8& name,
DisplayID display,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags) = 0;
-
+
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
virtual status_t destroySurface(SurfaceID sid) = 0;
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
virtual status_t setState(int32_t count, const layer_state_t* states) = 0;
};
// ----------------------------------------------------------------------------
-class BnSurfaceFlingerClient : public BnInterface<ISurfaceFlingerClient>
+class BnSurfaceComposerClient : public BnInterface<ISurfaceComposerClient>
{
public:
virtual status_t onTransact( uint32_t code,
@@ -88,4 +97,4 @@ public:
}; // namespace android
-#endif // ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
+#endif // ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 0279d84..2957970 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -28,12 +28,15 @@
#include <ui/egl/android_natives.h>
#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
+
+#define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface"
namespace android {
// ---------------------------------------------------------------------------
+class GraphicBuffer;
class GraphicBufferMapper;
class IOMX;
class Rect;
@@ -41,6 +44,7 @@ class Surface;
class SurfaceComposerClient;
class SharedClient;
class SharedBufferClient;
+class SurfaceClient;
// ---------------------------------------------------------------------------
@@ -104,7 +108,7 @@ private:
SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<ISurface>& surface,
- const ISurfaceFlingerClient::surface_data_t& data,
+ const ISurfaceComposerClient::surface_data_t& data,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
~SurfaceControl();
@@ -163,38 +167,36 @@ public:
// setSwapRectangle() is intended to be used by GL ES clients
void setSwapRectangle(const Rect& r);
-private:
- // can't be copied
- Surface& operator = (Surface& rhs);
- Surface(const Surface& rhs);
-
- Surface(const sp<SurfaceControl>& control);
- void init();
- ~Surface();
-
- friend class SurfaceComposerClient;
- friend class SurfaceControl;
-
+private:
+ /*
+ * Android frameworks friends
+ * (eventually this should go away and be replaced by proper APIs)
+ */
// camera and camcorder need access to the ISurface binder interface for preview
friend class Camera;
friend class MediaRecorder;
- // mediaplayer needs access to ISurface for display
+ // MediaPlayer needs access to ISurface for display
friend class MediaPlayer;
friend class IOMX;
// this is just to be able to write some unit tests
friend class Test;
- sp<SurfaceComposerClient> getClient() const;
- sp<ISurface> getISurface() const;
+private:
+ friend class SurfaceComposerClient;
+ friend class SurfaceControl;
- status_t getBufferLocked(int index, int usage);
-
- status_t validate() const;
+ // can't be copied
+ Surface& operator = (Surface& rhs);
+ Surface(const Surface& rhs);
- inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
- inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
-
+ Surface(const sp<SurfaceControl>& control);
+ ~Surface();
+
+
+ /*
+ * android_native_window_t hooks
+ */
static int setSwapInterval(android_native_window_t* window, int interval);
static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
@@ -208,21 +210,61 @@ private:
int query(int what, int* value);
int perform(int operation, va_list args);
- status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
-
void dispatch_setUsage(va_list args);
int dispatch_connect(va_list args);
int dispatch_disconnect(va_list args);
+ int dispatch_crop(va_list args);
+ int dispatch_set_buffer_count(va_list args);
+ int dispatch_set_buffers_geometry(va_list args);
void setUsage(uint32_t reqUsage);
int connect(int api);
int disconnect(int api);
+ int crop(Rect const* rect);
+ int setBufferCount(int bufferCount);
+ int setBuffersGeometry(int w, int h, int format);
- uint32_t getUsage() const;
- int getConnectedApi() const;
+ /*
+ * private stuff...
+ */
+ void init();
+ status_t validate() const;
+ status_t initCheck() const;
+ sp<ISurface> getISurface() const;
+
+ inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
+ inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
+
+ status_t getBufferLocked(int index,
+ uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
+ int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
+
+ int getConnectedApi() const;
+ bool needNewBuffer(int bufIdx,
+ uint32_t *pWidth, uint32_t *pHeight,
+ uint32_t *pFormat, uint32_t *pUsage) const;
+
+ class BufferInfo {
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mFormat;
+ uint32_t mUsage;
+ mutable uint32_t mDirty;
+ enum {
+ GEOMETRY = 0x01
+ };
+ public:
+ BufferInfo();
+ void set(uint32_t w, uint32_t h, uint32_t format);
+ void set(uint32_t usage);
+ void get(uint32_t *pWidth, uint32_t *pHeight,
+ uint32_t *pFormat, uint32_t *pUsage) const;
+ bool validateBuffer(const sp<GraphicBuffer>& buffer) const;
+ };
+
// constants
- sp<SurfaceComposerClient> mClient;
+ sp<SurfaceClient> mClient;
sp<ISurface> mSurface;
SurfaceID mToken;
uint32_t mIdentity;
@@ -230,22 +272,26 @@ private:
uint32_t mFlags;
GraphicBufferMapper& mBufferMapper;
SharedBufferClient* mSharedBufferClient;
+ status_t mInitCheck;
// protected by mSurfaceLock
Rect mSwapRectangle;
- uint32_t mUsage;
int mConnected;
+ Rect mNextBufferCrop;
+ BufferInfo mBufferInfo;
// protected by mSurfaceLock. These are also used from lock/unlock
// but in that case, they must be called form the same thread.
- sp<GraphicBuffer> mBuffers[2];
mutable Region mDirtyRegion;
// must be used from the lock/unlock thread
sp<GraphicBuffer> mLockedBuffer;
sp<GraphicBuffer> mPostedBuffer;
mutable Region mOldDirtyRegion;
- bool mNeedFullUpdate;
+ bool mReserved;
+
+ // only used from dequeueBuffer()
+ Vector< sp<GraphicBuffer> > mBuffers;
// query() must be called from dequeueBuffer() thread
uint32_t mWidth;
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index 9d0f0cb..8e28a81 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -40,7 +40,9 @@ class SharedClient;
class ISurfaceComposer;
class DisplayInfo;
-class SurfaceComposerClient : virtual public RefBase
+// ---------------------------------------------------------------------------
+
+class SurfaceComposerClient : public RefBase
{
public:
SurfaceComposerClient();
@@ -52,10 +54,6 @@ public:
// Return the connection of this client
sp<IBinder> connection() const;
- // Retrieve a client for an existing connection.
- static sp<SurfaceComposerClient>
- clientForConnection(const sp<IBinder>& conn);
-
// Forcibly remove connection before all references have gone away.
void dispose();
@@ -123,13 +121,6 @@ public:
status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0);
-private:
- friend class Surface;
- friend class SurfaceControl;
-
- SurfaceComposerClient(const sp<ISurfaceComposer>& sm,
- const sp<IBinder>& conn);
-
status_t hide(SurfaceID id);
status_t show(SurfaceID id, int32_t layer = -1);
status_t freeze(SurfaceID id);
@@ -142,32 +133,45 @@ private:
status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy);
status_t setPosition(SurfaceID id, int32_t x, int32_t y);
status_t setSize(SurfaceID id, uint32_t w, uint32_t h);
-
- void signalServer();
-
status_t destroySurface(SurfaceID sid);
- void _init(const sp<ISurfaceComposer>& sm,
- const sp<ISurfaceFlingerClient>& conn);
-
- inline layer_state_t* _get_state_l(SurfaceID id);
- layer_state_t* _lockLayerState(SurfaceID id);
- inline void _unlockLayerState();
+private:
+ virtual void onFirstRef();
+ inline layer_state_t* get_state_l(SurfaceID id);
+ layer_state_t* lockLayerState(SurfaceID id);
+ inline void unlockLayerState();
mutable Mutex mLock;
- layer_state_t* mPrebuiltLayerState;
SortedVector<layer_state_t> mStates;
int32_t mTransactionOpen;
+ layer_state_t* mPrebuiltLayerState;
// these don't need to be protected because they never change
// after assignment
status_t mStatus;
- SharedClient* mControl;
- sp<IMemoryHeap> mControlMemory;
- sp<ISurfaceFlingerClient> mClient;
- sp<ISurfaceComposer> mSignalServer;
+ sp<ISurfaceComposerClient> mClient;
};
+// ---------------------------------------------------------------------------
+
+class SurfaceClient : public RefBase
+{
+ // all these attributes are constants
+ status_t mStatus;
+ SharedClient* mControl;
+ sp<IMemoryHeap> mControlMemory;
+ sp<IBinder> mConnection;
+ sp<ISurfaceComposer> mComposerService;
+ void init(const sp<IBinder>& conn);
+public:
+ explicit SurfaceClient(const sp<IBinder>& conn);
+ explicit SurfaceClient(const sp<SurfaceComposerClient>& client);
+ status_t initCheck() const;
+ SharedClient* getSharedClient() const;
+ void signalServer() const;
+};
+
+// ---------------------------------------------------------------------------
}; // namespace android
#endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 741d763..54b8236 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -73,9 +73,9 @@ private:
struct alloc_rec_t {
uint32_t w;
uint32_t h;
+ uint32_t s;
PixelFormat format;
uint32_t usage;
- void* vaddr;
size_t size;
};
diff --git a/include/ui/android_native_buffer.h b/include/ui/android_native_buffer.h
index 9c92af8..402843e 100644
--- a/include/ui/android_native_buffer.h
+++ b/include/ui/android_native_buffer.h
@@ -33,6 +33,15 @@ typedef struct android_native_buffer_t
common.version = sizeof(android_native_buffer_t);
memset(common.reserved, 0, sizeof(common.reserved));
}
+
+ // Implement the methods that sp<android_native_buffer_t> expects so that it
+ // can be used to automatically refcount android_native_buffer_t's.
+ void incStrong(const void* id) const {
+ common.incRef(const_cast<android_native_base_t*>(&common));
+ }
+ void decStrong(const void* id) const {
+ common.decRef(const_cast<android_native_base_t*>(&common));
+ }
#endif
struct android_native_base_t common;
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 773fd93..171f3df 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -41,6 +41,14 @@ extern "C" {
struct android_native_buffer_t;
+typedef struct android_native_rect_t
+{
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+} android_native_rect_t;
+
// ---------------------------------------------------------------------------
typedef struct android_native_base_t
@@ -63,15 +71,18 @@ typedef struct android_native_base_t
/* attributes queriable with query() */
enum {
NATIVE_WINDOW_WIDTH = 0,
- NATIVE_WINDOW_HEIGHT = 1,
- NATIVE_WINDOW_FORMAT = 2,
+ NATIVE_WINDOW_HEIGHT,
+ NATIVE_WINDOW_FORMAT,
};
/* valid operations for the (*perform)() hook */
enum {
NATIVE_WINDOW_SET_USAGE = 0,
- NATIVE_WINDOW_CONNECT = 1,
- NATIVE_WINDOW_DISCONNECT = 2
+ NATIVE_WINDOW_CONNECT,
+ NATIVE_WINDOW_DISCONNECT,
+ NATIVE_WINDOW_SET_CROP,
+ NATIVE_WINDOW_SET_BUFFER_COUNT,
+ NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
};
/* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -89,6 +100,15 @@ typedef struct android_native_window_t
common.version = sizeof(android_native_window_t);
memset(common.reserved, 0, sizeof(common.reserved));
}
+
+ // Implement the methods that sp<android_native_window_t> expects so that it
+ // can be used to automatically refcount android_native_window_t's.
+ void incStrong(const void* id) const {
+ common.incRef(const_cast<android_native_base_t*>(&common));
+ }
+ void decStrong(const void* id) const {
+ common.decRef(const_cast<android_native_base_t*>(&common));
+ }
#endif
struct android_native_base_t common;
@@ -125,7 +145,7 @@ typedef struct android_native_window_t
*
* Returns 0 on success or -errno on error.
*/
- int (*dequeueBuffer)(struct android_native_window_t* window,
+ int (*dequeueBuffer)(struct android_native_window_t* window,
struct android_native_buffer_t** buffer);
/*
@@ -171,6 +191,9 @@ typedef struct android_native_window_t
* NATIVE_WINDOW_SET_USAGE
* NATIVE_WINDOW_CONNECT
* NATIVE_WINDOW_DISCONNECT
+ * NATIVE_WINDOW_SET_CROP
+ * NATIVE_WINDOW_SET_BUFFER_COUNT
+ * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY
*
*/
@@ -182,8 +205,9 @@ typedef struct android_native_window_t
/*
- * native_window_set_usage() sets the intended usage flags for the next
- * buffers acquired with (*lockBuffer)() and on.
+ * native_window_set_usage(..., usage)
+ * Sets the intended usage flags for the next buffers
+ * acquired with (*lockBuffer)() and on.
* By default (if this function is never called), a usage of
* GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
* is assumed.
@@ -198,8 +222,8 @@ static inline int native_window_set_usage(
}
/*
- * native_window_connect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made current.
+ * native_window_connect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made current.
* Returns -EINVAL if for some reason the window cannot be connected, which
* can happen if it's connected to some other API.
*/
@@ -210,8 +234,8 @@ static inline int native_window_connect(
}
/*
- * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made not current.
+ * native_window_disconnect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made not current.
* An error is returned if for instance the window wasn't connected in the
* first place.
*/
@@ -221,6 +245,54 @@ static inline int native_window_disconnect(
return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
}
+/*
+ * native_window_set_crop(..., crop)
+ * Sets which region of the next queued buffers needs to be considered.
+ * A buffer's crop region is scaled to match the surface's size.
+ *
+ * The specified crop region applies to all buffers queued after it is called.
+ *
+ * if 'crop' is NULL, subsequently queued buffers won't be cropped.
+ *
+ * An error is returned if for instance the crop region is invalid,
+ * out of the buffer's bound or if the window is invalid.
+ */
+static inline int native_window_set_crop(
+ android_native_window_t* window,
+ android_native_rect_t const * crop)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
+}
+
+/*
+ * native_window_set_buffer_count(..., count)
+ * Sets the number of buffers associated with this native window.
+ */
+static inline int native_window_set_buffer_count(
+ android_native_window_t* window,
+ size_t bufferCount)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
+}
+
+/*
+ * native_window_set_buffers_geometry(..., int w, int h, int format)
+ * All buffers dequeued after this call will have the geometry specified.
+ * In particular, all buffers will have a fixed-size, independent form the
+ * native-window size. They will be appropriately scaled to the window-size
+ * upon composition.
+ *
+ * If all parameters are 0, the normal behavior is restored. That is,
+ * dequeued buffers following this call will be sized to the window's size.
+ *
+ */
+static inline int native_window_set_buffers_geometry(
+ android_native_window_t* window,
+ int w, int h, int format)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
+ w, h, format);
+}
// ---------------------------------------------------------------------------
@@ -263,6 +335,15 @@ namespace android {
template <typename NATIVE_TYPE, typename TYPE, typename REF>
class EGLNativeBase : public NATIVE_TYPE, public REF
{
+public:
+ // Disambiguate between the incStrong in REF and NATIVE_TYPE
+ void incStrong(const void* id) const {
+ REF::incStrong(id);
+ }
+ void decStrong(const void* id) const {
+ REF::decStrong(id);
+ }
+
protected:
typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE;
EGLNativeBase() : NATIVE_TYPE(), REF() {
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index b701ce7..c7d9ff1 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -933,6 +933,7 @@ struct ResTable_config
SCREENSIZE_SMALL = 0x01,
SCREENSIZE_NORMAL = 0x02,
SCREENSIZE_LARGE = 0x03,
+ SCREENSIZE_XLARGE = 0x04,
// screenLayout bits for wide/long screen variation.
MASK_SCREENLONG = 0x30,
@@ -1208,7 +1209,28 @@ struct ResTable_config
if (screenLayout || o.screenLayout) {
if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
&& (requested->screenLayout & MASK_SCREENSIZE)) {
- return (screenLayout & MASK_SCREENSIZE);
+ // A little backwards compatibility here: undefined is
+ // considered equivalent to normal. But only if the
+ // requested size is at least normal; otherwise, small
+ // is better than the default.
+ int mySL = (screenLayout & MASK_SCREENSIZE);
+ int oSL = (o.screenLayout & MASK_SCREENSIZE);
+ int fixedMySL = mySL;
+ int fixedOSL = oSL;
+ if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
+ if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
+ if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
+ }
+ // For screen size, the best match is the one that is
+ // closest to the requested screen size, but not over
+ // (the not over part is dealt with in match() below).
+ if (fixedMySL == fixedOSL) {
+ // If the two are the same, but 'this' is actually
+ // undefined, then the other is really a better match.
+ if (mySL == 0) return false;
+ return true;
+ }
+ return fixedMySL >= fixedOSL;
}
if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
&& (requested->screenLayout & MASK_SCREENLONG)) {
@@ -1370,8 +1392,11 @@ struct ResTable_config
if (screenConfig != 0) {
const int screenSize = screenLayout&MASK_SCREENSIZE;
const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
- if (setScreenSize != 0 && screenSize != 0
- && screenSize != setScreenSize) {
+ // Any screen sizes for larger screens than the setting do not
+ // match.
+ if ((setScreenSize != 0 && screenSize != 0
+ && screenSize > setScreenSize) ||
+ (setScreenSize == 0 && screenSize != 0)) {
return false;
}
diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h
index bc7626a..3b975b4 100644
--- a/include/utils/Singleton.h
+++ b/include/utils/Singleton.h
@@ -54,11 +54,13 @@ private:
* (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
* and avoid to have a copy of them in each compilation units Singleton<TYPE>
* is used.
+ * NOTE: we use a version of Mutex ctor that takes a parameter, because
+ * for some unknown reason using the default ctor doesn't emit the variable!
*/
-#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \
- template class Singleton< TYPE >; \
- template< class TYPE > Mutex Singleton< TYPE >::sLock; \
+#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \
+ template class Singleton< TYPE >; \
+ template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE); \
template<> TYPE* Singleton< TYPE >::sInstance(0);
diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h
index 30e0036..e38bf66 100644
--- a/include/utils/ZipFileCRO.h
+++ b/include/utils/ZipFileCRO.h
@@ -47,8 +47,8 @@ extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip,
const char* fileName);
extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
- int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
+ int* pMethod, size_t* pUncompLen,
+ size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);
diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h
index 51c4f2f..97d31f4 100644
--- a/include/utils/ZipFileRO.h
+++ b/include/utils/ZipFileRO.h
@@ -58,14 +58,19 @@ typedef void* ZipEntryRO;
class ZipFileRO {
public:
ZipFileRO()
- : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL)
+ : mFd(-1), mFileName(NULL), mFileLength(-1),
+ mDirectoryMap(NULL),
+ mNumEntries(-1), mDirectoryOffset(-1),
+ mHashTableSize(-1), mHashTable(NULL)
{}
~ZipFileRO() {
free(mHashTable);
- if (mFileMap)
- mFileMap->release();
+ if (mDirectoryMap)
+ mDirectoryMap->release();
if (mFd >= 0)
close(mFd);
+ if (mFileName)
+ free(mFileName);
}
/*
@@ -118,8 +123,8 @@ public:
* Returns "false" if "entry" is bogus or if the data in the Zip file
* appears to be bad.
*/
- bool getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
+ bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+ size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
/*
* Create a new FileMap object that maps a subset of the archive. For
@@ -155,13 +160,13 @@ public:
* Utility function: uncompress deflated data, buffer to buffer.
*/
static bool inflateBuffer(void* outBuf, const void* inBuf,
- long uncompLen, long compLen);
+ size_t uncompLen, size_t compLen);
/*
* Utility function: uncompress deflated data, buffer to fd.
*/
static bool inflateBuffer(int fd, const void* inBuf,
- long uncompLen, long compLen);
+ size_t uncompLen, size_t compLen);
/*
* Some basic functions for raw data manipulation. "LE" means
@@ -179,6 +184,9 @@ private:
ZipFileRO(const ZipFileRO& src);
ZipFileRO& operator=(const ZipFileRO& src);
+ /* locate and parse the central directory */
+ bool mapCentralDirectory(void);
+
/* parse the archive, prepping internal structures */
bool parseZipArchive(void);
@@ -203,12 +211,21 @@ private:
/* open Zip archive */
int mFd;
+ /* zip file name */
+ char* mFileName;
+
+ /* length of file */
+ size_t mFileLength;
+
/* mapped file */
- FileMap* mFileMap;
+ FileMap* mDirectoryMap;
/* number of entries in the Zip archive */
int mNumEntries;
+ /* CD directory offset in the Zip archive */
+ off_t mDirectoryOffset;
+
/*
* We know how many entries are in the Zip archive, so we have a
* fixed-size hash table. We probe for an empty slot.
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 5ac0c5e..1bcfaed 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -295,6 +295,96 @@ typedef Mutex::Autolock AutoMutex;
/*****************************************************************************/
+#if defined(HAVE_PTHREADS)
+
+/*
+ * Simple mutex class. The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it. They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class RWLock {
+public:
+ enum {
+ PRIVATE = 0,
+ SHARED = 1
+ };
+
+ RWLock();
+ RWLock(const char* name);
+ RWLock(int type, const char* name = NULL);
+ ~RWLock();
+
+ status_t readLock();
+ status_t tryReadLock();
+ status_t writeLock();
+ status_t tryWriteLock();
+ void unlock();
+
+ class AutoRLock {
+ public:
+ inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); }
+ inline ~AutoRLock() { mLock.unlock(); }
+ private:
+ RWLock& mLock;
+ };
+
+ class AutoWLock {
+ public:
+ inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); }
+ inline ~AutoWLock() { mLock.unlock(); }
+ private:
+ RWLock& mLock;
+ };
+
+private:
+ // A RWLock cannot be copied
+ RWLock(const RWLock&);
+ RWLock& operator = (const RWLock&);
+
+ pthread_rwlock_t mRWLock;
+};
+
+inline RWLock::RWLock() {
+ pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(const char* name) {
+ pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(int type, const char* name) {
+ if (type == SHARED) {
+ pthread_rwlockattr_t attr;
+ pthread_rwlockattr_init(&attr);
+ pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ pthread_rwlock_init(&mRWLock, &attr);
+ pthread_rwlockattr_destroy(&attr);
+ } else {
+ pthread_rwlock_init(&mRWLock, NULL);
+ }
+}
+inline RWLock::~RWLock() {
+ pthread_rwlock_destroy(&mRWLock);
+}
+inline status_t RWLock::readLock() {
+ return -pthread_rwlock_rdlock(&mRWLock);
+}
+inline status_t RWLock::tryReadLock() {
+ return -pthread_rwlock_tryrdlock(&mRWLock);
+}
+inline status_t RWLock::writeLock() {
+ return -pthread_rwlock_wrlock(&mRWLock);
+}
+inline status_t RWLock::tryWriteLock() {
+ return -pthread_rwlock_trywrlock(&mRWLock);
+}
+inline void RWLock::unlock() {
+ pthread_rwlock_unlock(&mRWLock);
+}
+
+#endif // HAVE_PTHREADS
+
+/*****************************************************************************/
+
/*
* Condition variable class. The implementation is system-dependent.
*