summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/private/surfaceflinger/SharedBufferStack.h104
-rw-r--r--include/surfaceflinger/ISurfaceFlingerClient.h9
-rw-r--r--include/surfaceflinger/Surface.h63
-rw-r--r--include/ui/GraphicBufferAllocator.h2
-rw-r--r--include/ui/egl/android_natives.h38
-rw-r--r--include/utils/ResourceTypes.h31
6 files changed, 151 insertions, 96 deletions
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 9b5a1e0..2504d39 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -58,7 +58,7 @@ 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_BUFFER_MAX = 16;
const unsigned int NUM_DISPLAY_MAX = 4;
// ----------------------------------------------------------------------------
@@ -69,7 +69,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 +82,31 @@ 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];
- };
-
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,11 +118,13 @@ 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
};
// ----------------------------------------------------------------------------
@@ -152,6 +168,7 @@ protected:
SharedBufferStack* const mSharedStack;
const int mNumBuffers;
const int mIdentity;
+ int32_t computeTail() const;
friend struct Update;
friend struct QueueUpdate;
@@ -160,61 +177,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 +216,12 @@ 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);
private:
friend struct Condition;
friend struct DequeueCondition;
friend struct LockCondition;
-
- int32_t computeTail() const;
struct QueueUpdate : public UpdateBase {
inline QueueUpdate(SharedBufferBase* sbb);
@@ -260,18 +237,20 @@ 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 tail;
+ int32_t undoDequeueTail;
+ int32_t queued_head;
// statistics...
nsecs_t mDequeueTime[NUM_BUFFER_MAX];
};
@@ -318,8 +297,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"; }
};
};
@@ -349,8 +328,7 @@ struct surface_flinger_cblk_t // 4KB 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/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceFlingerClient.h
index d257645..c96432f 100644
--- a/include/surfaceflinger/ISurfaceFlingerClient.h
+++ b/include/surfaceflinger/ISurfaceFlingerClient.h
@@ -59,6 +59,9 @@ public:
virtual sp<IMemoryHeap> getControlBlock() const = 0;
+ /*
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
virtual sp<ISurface> createSurface( surface_data_t* data,
int pid,
const String8& name,
@@ -68,8 +71,14 @@ public:
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;
};
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 0279d84..7ab3a00 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -30,6 +30,8 @@
#include <surfaceflinger/ISurface.h>
#include <surfaceflinger/ISurfaceFlingerClient.h>
+#define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface"
+
namespace android {
// ---------------------------------------------------------------------------
@@ -163,38 +165,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,15 +208,29 @@ 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);
void setUsage(uint32_t reqUsage);
int connect(int api);
int disconnect(int api);
+ int crop(Rect const* rect);
+
+ /*
+ * private stuff...
+ */
+ void init();
+ status_t validate() const;
+ sp<SurfaceComposerClient> getClient() const;
+ sp<ISurface> getISurface() const;
+
+ inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
+ inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
+
+ status_t getBufferLocked(int index, int usage);
+ int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
uint32_t getUsage() const;
int getConnectedApi() const;
@@ -235,6 +249,7 @@ private:
Rect mSwapRectangle;
uint32_t mUsage;
int mConnected;
+ Rect mNextBufferCrop;
// protected by mSurfaceLock. These are also used from lock/unlock
// but in that case, they must be called form the same thread.
@@ -245,7 +260,7 @@ private:
sp<GraphicBuffer> mLockedBuffer;
sp<GraphicBuffer> mPostedBuffer;
mutable Region mOldDirtyRegion;
- bool mNeedFullUpdate;
+ bool mReserved;
// query() must be called from dequeueBuffer() thread
uint32_t mWidth;
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/egl/android_natives.h b/include/ui/egl/android_natives.h
index 773fd93..471c3c7 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,16 @@ 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,
};
/* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -125,7 +134,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 +180,7 @@ typedef struct android_native_window_t
* NATIVE_WINDOW_SET_USAGE
* NATIVE_WINDOW_CONNECT
* NATIVE_WINDOW_DISCONNECT
+ * NATIVE_WINDOW_SET_CROP
*
*/
@@ -221,6 +231,24 @@ 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);
+}
// ---------------------------------------------------------------------------
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;
}