Loading include/private/surfaceflinger/SharedBufferStack.h +20 −9 Original line number Diff line number Diff line Loading @@ -70,9 +70,9 @@ class SharedClient; // ---------------------------------------------------------------------------- // 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX // 4 * (11 + 7 + (1 + 2*6)*16) * 31 // 904 * 31 // = ~27 KiB (28024) // 4 * (11 + 7 + (1 + 2*7)*16) * 31 // 1032 * 31 // = ~27 KiB (31992) class SharedBufferStack { Loading @@ -82,21 +82,31 @@ class SharedBufferStack friend class SharedBufferServer; public: 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; uint16_t rects[4*NUM_RECT_MAX]; SmallRect rects[NUM_RECT_MAX]; }; struct Statistics { // 4 longs typedef int32_t usecs_t; usecs_t totalTime; usecs_t reserved[3]; 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 Loading @@ -113,7 +123,7 @@ public: int32_t reserved32[6]; Statistics stats; int32_t reserved; FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 832 bytes BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes }; // ---------------------------------------------------------------------------- Loading Loading @@ -243,6 +253,7 @@ 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; Loading include/surfaceflinger/ISurfaceFlingerClient.h +9 −0 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; }; Loading include/surfaceflinger/Surface.h +3 −0 Original line number Diff line number Diff line Loading @@ -215,10 +215,12 @@ private: 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); uint32_t getUsage() const; int getConnectedApi() const; Loading @@ -237,6 +239,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. Loading include/ui/egl/android_natives.h +33 −5 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 */ Loading Loading @@ -171,6 +180,7 @@ typedef struct android_native_window_t * NATIVE_WINDOW_SET_USAGE * NATIVE_WINDOW_CONNECT * NATIVE_WINDOW_DISCONNECT * NATIVE_WINDOW_SET_CROP * */ Loading Loading @@ -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); } // --------------------------------------------------------------------------- Loading libs/surfaceflinger_client/SharedBufferStack.cpp +39 −16 Original line number Diff line number Diff line Loading @@ -67,6 +67,18 @@ void SharedBufferStack::init(int32_t i) identity = i; } status_t SharedBufferStack::setCrop(int buffer, const Rect& crop) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) return BAD_INDEX; buffers[buffer].crop.l = uint16_t(crop.left); buffers[buffer].crop.t = uint16_t(crop.top); buffers[buffer].crop.r = uint16_t(crop.right); buffers[buffer].crop.b = uint16_t(crop.bottom); return NO_ERROR; } status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) Loading @@ -75,21 +87,21 @@ status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty) // in the current implementation we only send a single rectangle size_t count; Rect const* r = dirty.getArray(&count); FlatRegion& reg(dirtyRegion[buffer]); FlatRegion& reg(buffers[buffer].dirtyRegion); if (count > FlatRegion::NUM_RECT_MAX) { const Rect bounds(dirty.getBounds()); reg.count = 1; reg.rects[0] = uint16_t(bounds.left); reg.rects[1] = uint16_t(bounds.top); reg.rects[2] = uint16_t(bounds.right); reg.rects[3] = uint16_t(bounds.bottom); reg.rects[0].l = uint16_t(bounds.left); reg.rects[0].t = uint16_t(bounds.top); reg.rects[0].r = uint16_t(bounds.right); reg.rects[0].b = uint16_t(bounds.bottom); } else { reg.count = count; for (size_t i=0 ; i<count ; i++) { reg.rects[i*4 + 0] = uint16_t(r[i].left); reg.rects[i*4 + 1] = uint16_t(r[i].top); reg.rects[i*4 + 2] = uint16_t(r[i].right); reg.rects[i*4 + 3] = uint16_t(r[i].bottom); reg.rects[i].l = uint16_t(r[i].left); reg.rects[i].t = uint16_t(r[i].top); reg.rects[i].r = uint16_t(r[i].right); reg.rects[i].b = uint16_t(r[i].bottom); } } return NO_ERROR; Loading @@ -101,19 +113,24 @@ Region SharedBufferStack::getDirtyRegion(int buffer) const if (uint32_t(buffer) >= NUM_BUFFER_MAX) return res; const FlatRegion& reg(dirtyRegion[buffer]); const FlatRegion& reg(buffers[buffer].dirtyRegion); if (reg.count > FlatRegion::NUM_RECT_MAX) return res; if (reg.count == 1) { res.set(Rect(reg.rects[0], reg.rects[1], reg.rects[2], reg.rects[3])); const Rect r( reg.rects[0].l, reg.rects[0].t, reg.rects[0].r, reg.rects[0].b); res.set(r); } else { for (size_t i=0 ; i<reg.count ; i++) { const Rect r( reg.rects[i*4 + 0], reg.rects[i*4 + 1], reg.rects[i*4 + 2], reg.rects[i*4 + 3]); reg.rects[i].l, reg.rects[i].t, reg.rects[i].r, reg.rects[i].b); res.orSelf(r); } } Loading Loading @@ -372,6 +389,12 @@ bool SharedBufferClient::needNewBuffer(int buffer) const return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0; } status_t SharedBufferClient::setCrop(int buffer, const Rect& crop) { SharedBufferStack& stack( *mSharedStack ); return stack.setCrop(buffer, crop); } status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg) { SharedBufferStack& stack( *mSharedStack ); Loading @@ -389,7 +412,7 @@ SharedBufferServer::SharedBufferServer(SharedClient* sharedClient, mSharedStack->available = num; mSharedStack->queued = 0; mSharedStack->reallocMask = 0; memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion)); memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers)); } ssize_t SharedBufferServer::retireAndLock() Loading Loading
include/private/surfaceflinger/SharedBufferStack.h +20 −9 Original line number Diff line number Diff line Loading @@ -70,9 +70,9 @@ class SharedClient; // ---------------------------------------------------------------------------- // 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX // 4 * (11 + 7 + (1 + 2*6)*16) * 31 // 904 * 31 // = ~27 KiB (28024) // 4 * (11 + 7 + (1 + 2*7)*16) * 31 // 1032 * 31 // = ~27 KiB (31992) class SharedBufferStack { Loading @@ -82,21 +82,31 @@ class SharedBufferStack friend class SharedBufferServer; public: 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; uint16_t rects[4*NUM_RECT_MAX]; SmallRect rects[NUM_RECT_MAX]; }; struct Statistics { // 4 longs typedef int32_t usecs_t; usecs_t totalTime; usecs_t reserved[3]; 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 Loading @@ -113,7 +123,7 @@ public: int32_t reserved32[6]; Statistics stats; int32_t reserved; FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 832 bytes BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes }; // ---------------------------------------------------------------------------- Loading Loading @@ -243,6 +253,7 @@ 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; Loading
include/surfaceflinger/ISurfaceFlingerClient.h +9 −0 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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; }; Loading
include/surfaceflinger/Surface.h +3 −0 Original line number Diff line number Diff line Loading @@ -215,10 +215,12 @@ private: 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); uint32_t getUsage() const; int getConnectedApi() const; Loading @@ -237,6 +239,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. Loading
include/ui/egl/android_natives.h +33 −5 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 */ Loading Loading @@ -171,6 +180,7 @@ typedef struct android_native_window_t * NATIVE_WINDOW_SET_USAGE * NATIVE_WINDOW_CONNECT * NATIVE_WINDOW_DISCONNECT * NATIVE_WINDOW_SET_CROP * */ Loading Loading @@ -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); } // --------------------------------------------------------------------------- Loading
libs/surfaceflinger_client/SharedBufferStack.cpp +39 −16 Original line number Diff line number Diff line Loading @@ -67,6 +67,18 @@ void SharedBufferStack::init(int32_t i) identity = i; } status_t SharedBufferStack::setCrop(int buffer, const Rect& crop) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) return BAD_INDEX; buffers[buffer].crop.l = uint16_t(crop.left); buffers[buffer].crop.t = uint16_t(crop.top); buffers[buffer].crop.r = uint16_t(crop.right); buffers[buffer].crop.b = uint16_t(crop.bottom); return NO_ERROR; } status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) Loading @@ -75,21 +87,21 @@ status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty) // in the current implementation we only send a single rectangle size_t count; Rect const* r = dirty.getArray(&count); FlatRegion& reg(dirtyRegion[buffer]); FlatRegion& reg(buffers[buffer].dirtyRegion); if (count > FlatRegion::NUM_RECT_MAX) { const Rect bounds(dirty.getBounds()); reg.count = 1; reg.rects[0] = uint16_t(bounds.left); reg.rects[1] = uint16_t(bounds.top); reg.rects[2] = uint16_t(bounds.right); reg.rects[3] = uint16_t(bounds.bottom); reg.rects[0].l = uint16_t(bounds.left); reg.rects[0].t = uint16_t(bounds.top); reg.rects[0].r = uint16_t(bounds.right); reg.rects[0].b = uint16_t(bounds.bottom); } else { reg.count = count; for (size_t i=0 ; i<count ; i++) { reg.rects[i*4 + 0] = uint16_t(r[i].left); reg.rects[i*4 + 1] = uint16_t(r[i].top); reg.rects[i*4 + 2] = uint16_t(r[i].right); reg.rects[i*4 + 3] = uint16_t(r[i].bottom); reg.rects[i].l = uint16_t(r[i].left); reg.rects[i].t = uint16_t(r[i].top); reg.rects[i].r = uint16_t(r[i].right); reg.rects[i].b = uint16_t(r[i].bottom); } } return NO_ERROR; Loading @@ -101,19 +113,24 @@ Region SharedBufferStack::getDirtyRegion(int buffer) const if (uint32_t(buffer) >= NUM_BUFFER_MAX) return res; const FlatRegion& reg(dirtyRegion[buffer]); const FlatRegion& reg(buffers[buffer].dirtyRegion); if (reg.count > FlatRegion::NUM_RECT_MAX) return res; if (reg.count == 1) { res.set(Rect(reg.rects[0], reg.rects[1], reg.rects[2], reg.rects[3])); const Rect r( reg.rects[0].l, reg.rects[0].t, reg.rects[0].r, reg.rects[0].b); res.set(r); } else { for (size_t i=0 ; i<reg.count ; i++) { const Rect r( reg.rects[i*4 + 0], reg.rects[i*4 + 1], reg.rects[i*4 + 2], reg.rects[i*4 + 3]); reg.rects[i].l, reg.rects[i].t, reg.rects[i].r, reg.rects[i].b); res.orSelf(r); } } Loading Loading @@ -372,6 +389,12 @@ bool SharedBufferClient::needNewBuffer(int buffer) const return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0; } status_t SharedBufferClient::setCrop(int buffer, const Rect& crop) { SharedBufferStack& stack( *mSharedStack ); return stack.setCrop(buffer, crop); } status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg) { SharedBufferStack& stack( *mSharedStack ); Loading @@ -389,7 +412,7 @@ SharedBufferServer::SharedBufferServer(SharedClient* sharedClient, mSharedStack->available = num; mSharedStack->queued = 0; mSharedStack->reallocMask = 0; memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion)); memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers)); } ssize_t SharedBufferServer::retireAndLock() Loading