Loading include/private/surfaceflinger/SharedBufferStack.h +10 −8 Original line number Diff line number Diff line Loading @@ -54,11 +54,6 @@ class SharedClient; // ---------------------------------------------------------------------------- // 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; Loading @@ -85,7 +80,7 @@ public: }; struct FlatRegion { // 52 bytes = 4 * (1 + 2*N) static const unsigned int NUM_RECT_MAX = 6; static const unsigned int NUM_RECT_MAX = 5; uint32_t count; SmallRect rects[NUM_RECT_MAX]; }; Loading @@ -93,13 +88,18 @@ public: struct BufferData { FlatRegion dirtyRegion; SmallRect crop; uint8_t transform; uint8_t reserved[3]; }; SharedBufferStack(); void init(int32_t identity); status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); status_t setTransform(int buffer, uint8_t transform); Region getDirtyRegion(int buffer) const; Rect getCrop(int buffer) const; uint32_t getTransform(int buffer) const; // these attributes are part of the conditions/updates volatile int32_t head; // server's current front buffer Loading @@ -117,7 +117,7 @@ public: int32_t reserved32[1]; Statistics stats; int32_t reserved; BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes BufferData buffers[NUM_BUFFER_MAX]; // 1024 bytes }; // ---------------------------------------------------------------------------- Loading Loading @@ -206,7 +206,7 @@ public: bool needNewBuffer(int buffer) const; status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); status_t setTransform(int buffer, uint32_t transform); class SetBufferCountCallback { friend class SharedBufferClient; Loading Loading @@ -275,6 +275,8 @@ public: status_t reallocateAllExcept(int buffer); int32_t getQueuedCount() const; Region getDirtyRegion(int buffer) const; Rect getCrop(int buffer) const; uint32_t getTransform(int buffer) const; status_t resize(int newNumBuffers); Loading include/surfaceflinger/Surface.h +3 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,7 @@ private: int dispatch_crop(va_list args); int dispatch_set_buffer_count(va_list args); int dispatch_set_buffers_geometry(va_list args); int dispatch_set_buffers_transform(va_list args); void setUsage(uint32_t reqUsage); int connect(int api); Loading @@ -223,6 +224,7 @@ private: int crop(Rect const* rect); int setBufferCount(int bufferCount); int setBuffersGeometry(int w, int h, int format); int setBuffersTransform(int transform); /* * private stuff... Loading Loading @@ -278,6 +280,7 @@ private: Rect mSwapRectangle; int mConnected; Rect mNextBufferCrop; uint32_t mNextBufferTransform; BufferInfo mBufferInfo; // protected by mSurfaceLock. These are also used from lock/unlock Loading include/ui/egl/android_natives.h +29 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ enum { NATIVE_WINDOW_SET_CROP, NATIVE_WINDOW_SET_BUFFER_COUNT, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, }; /* parameter for NATIVE_WINDOW_[DIS]CONNECT */ Loading @@ -92,6 +93,20 @@ enum { NATIVE_WINDOW_API_EGL = 1 }; /* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */ enum { /* flip source image horizontally */ NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H , /* flip source image vertically */ NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V, /* rotate source image 90 degrees clock-wise */ NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90, /* rotate source image 180 degrees */ NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, /* rotate source image 270 degrees clock-wise */ NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, }; struct ANativeWindow { #ifdef __cplusplus Loading Loading @@ -196,6 +211,7 @@ struct ANativeWindow * NATIVE_WINDOW_SET_CROP * NATIVE_WINDOW_SET_BUFFER_COUNT * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY * NATIVE_WINDOW_SET_BUFFERS_TRANSFORM * */ Loading Loading @@ -298,6 +314,19 @@ static inline int native_window_set_buffers_geometry( w, h, format); } /* * native_window_set_buffers_transform(..., int transform) * All buffers queued after this call will be displayed transformed according * to the transform parameter specified. */ static inline int native_window_set_buffers_transform( ANativeWindow* window, int transform) { return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, transform); } // --------------------------------------------------------------------------- /* FIXME: this is legacy for pixmaps */ Loading libs/surfaceflinger_client/SharedBufferStack.cpp +46 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,14 @@ status_t SharedBufferStack::setCrop(int buffer, const Rect& crop) return NO_ERROR; } status_t SharedBufferStack::setTransform(int buffer, uint8_t transform) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) return BAD_INDEX; buffers[buffer].transform = transform; return NO_ERROR; } status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) Loading Loading @@ -137,6 +145,26 @@ Region SharedBufferStack::getDirtyRegion(int buffer) const return res; } Rect SharedBufferStack::getCrop(int buffer) const { Rect res(-1, -1); if (uint32_t(buffer) >= NUM_BUFFER_MAX) return res; res.left = buffers[buffer].crop.l; res.top = buffers[buffer].crop.t; res.right = buffers[buffer].crop.r; res.bottom = buffers[buffer].crop.b; return res; } uint32_t SharedBufferStack::getTransform(int buffer) const { if (uint32_t(buffer) >= NUM_BUFFER_MAX) return 0; return buffers[buffer].transform; } // ---------------------------------------------------------------------------- SharedBufferBase::SharedBufferBase(SharedClient* sharedClient, Loading Loading @@ -433,6 +461,12 @@ status_t SharedBufferClient::setCrop(int buf, const Rect& crop) return stack.setCrop(buf, crop); } status_t SharedBufferClient::setTransform(int buf, uint32_t transform) { SharedBufferStack& stack( *mSharedStack ); return stack.setTransform(buf, uint8_t(transform)); } status_t SharedBufferClient::setDirtyRegion(int buf, const Region& reg) { SharedBufferStack& stack( *mSharedStack ); Loading Loading @@ -549,6 +583,18 @@ Region SharedBufferServer::getDirtyRegion(int buf) const return stack.getDirtyRegion(buf); } Rect SharedBufferServer::getCrop(int buf) const { SharedBufferStack& stack( *mSharedStack ); return stack.getCrop(buf); } uint32_t SharedBufferServer::getTransform(int buf) const { SharedBufferStack& stack( *mSharedStack ); return stack.getTransform(buf); } /* * NOTE: this is not thread-safe on the server-side, meaning * 'head' cannot move during this operation. The client-side Loading libs/surfaceflinger_client/Surface.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -422,8 +422,10 @@ void Surface::init() const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; const_cast<uint32_t&>(ANativeWindow::flags) = 0; mNextBufferTransform = 0; mConnected = 0; mSwapRectangle.makeInvalid(); mNextBufferCrop = Rect(0,0); // two buffers by default mBuffers.setCapacity(2); mBuffers.insertAt(0, 2); Loading Loading @@ -631,6 +633,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) } int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer)); mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform); mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop); mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion); err = mSharedBufferClient->queue(bufIdx); Loading Loading @@ -685,6 +688,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: res = dispatch_set_buffers_geometry( args ); break; case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: res = dispatch_set_buffers_transform( args ); break; default: res = NAME_NOT_FOUND; break; Loading Loading @@ -719,6 +725,11 @@ int Surface::dispatch_set_buffers_geometry(va_list args) { return setBuffersGeometry(w, h, f); } int Surface::dispatch_set_buffers_transform(va_list args) { int transform = va_arg(args, int); return setBuffersTransform(transform); } void Surface::setUsage(uint32_t reqUsage) { Mutex::Autolock _l(mSurfaceLock); Loading Loading @@ -765,6 +776,10 @@ int Surface::disconnect(int api) int Surface::crop(Rect const* rect) { // empty/invalid rects are not allowed if (rect->isEmpty()) return BAD_VALUE; Mutex::Autolock _l(mSurfaceLock); // TODO: validate rect size mNextBufferCrop = *rect; Loading Loading @@ -804,6 +819,13 @@ int Surface::setBuffersGeometry(int w, int h, int format) return NO_ERROR; } int Surface::setBuffersTransform(int transform) { Mutex::Autolock _l(mSurfaceLock); mNextBufferTransform = transform; return NO_ERROR; } // ---------------------------------------------------------------------------- int Surface::getConnectedApi() const Loading Loading
include/private/surfaceflinger/SharedBufferStack.h +10 −8 Original line number Diff line number Diff line Loading @@ -54,11 +54,6 @@ class SharedClient; // ---------------------------------------------------------------------------- // 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; Loading @@ -85,7 +80,7 @@ public: }; struct FlatRegion { // 52 bytes = 4 * (1 + 2*N) static const unsigned int NUM_RECT_MAX = 6; static const unsigned int NUM_RECT_MAX = 5; uint32_t count; SmallRect rects[NUM_RECT_MAX]; }; Loading @@ -93,13 +88,18 @@ public: struct BufferData { FlatRegion dirtyRegion; SmallRect crop; uint8_t transform; uint8_t reserved[3]; }; SharedBufferStack(); void init(int32_t identity); status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); status_t setTransform(int buffer, uint8_t transform); Region getDirtyRegion(int buffer) const; Rect getCrop(int buffer) const; uint32_t getTransform(int buffer) const; // these attributes are part of the conditions/updates volatile int32_t head; // server's current front buffer Loading @@ -117,7 +117,7 @@ public: int32_t reserved32[1]; Statistics stats; int32_t reserved; BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes BufferData buffers[NUM_BUFFER_MAX]; // 1024 bytes }; // ---------------------------------------------------------------------------- Loading Loading @@ -206,7 +206,7 @@ public: bool needNewBuffer(int buffer) const; status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); status_t setTransform(int buffer, uint32_t transform); class SetBufferCountCallback { friend class SharedBufferClient; Loading Loading @@ -275,6 +275,8 @@ public: status_t reallocateAllExcept(int buffer); int32_t getQueuedCount() const; Region getDirtyRegion(int buffer) const; Rect getCrop(int buffer) const; uint32_t getTransform(int buffer) const; status_t resize(int newNumBuffers); Loading
include/surfaceflinger/Surface.h +3 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,7 @@ private: int dispatch_crop(va_list args); int dispatch_set_buffer_count(va_list args); int dispatch_set_buffers_geometry(va_list args); int dispatch_set_buffers_transform(va_list args); void setUsage(uint32_t reqUsage); int connect(int api); Loading @@ -223,6 +224,7 @@ private: int crop(Rect const* rect); int setBufferCount(int bufferCount); int setBuffersGeometry(int w, int h, int format); int setBuffersTransform(int transform); /* * private stuff... Loading Loading @@ -278,6 +280,7 @@ private: Rect mSwapRectangle; int mConnected; Rect mNextBufferCrop; uint32_t mNextBufferTransform; BufferInfo mBufferInfo; // protected by mSurfaceLock. These are also used from lock/unlock Loading
include/ui/egl/android_natives.h +29 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ enum { NATIVE_WINDOW_SET_CROP, NATIVE_WINDOW_SET_BUFFER_COUNT, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, }; /* parameter for NATIVE_WINDOW_[DIS]CONNECT */ Loading @@ -92,6 +93,20 @@ enum { NATIVE_WINDOW_API_EGL = 1 }; /* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */ enum { /* flip source image horizontally */ NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H , /* flip source image vertically */ NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V, /* rotate source image 90 degrees clock-wise */ NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90, /* rotate source image 180 degrees */ NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, /* rotate source image 270 degrees clock-wise */ NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, }; struct ANativeWindow { #ifdef __cplusplus Loading Loading @@ -196,6 +211,7 @@ struct ANativeWindow * NATIVE_WINDOW_SET_CROP * NATIVE_WINDOW_SET_BUFFER_COUNT * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY * NATIVE_WINDOW_SET_BUFFERS_TRANSFORM * */ Loading Loading @@ -298,6 +314,19 @@ static inline int native_window_set_buffers_geometry( w, h, format); } /* * native_window_set_buffers_transform(..., int transform) * All buffers queued after this call will be displayed transformed according * to the transform parameter specified. */ static inline int native_window_set_buffers_transform( ANativeWindow* window, int transform) { return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, transform); } // --------------------------------------------------------------------------- /* FIXME: this is legacy for pixmaps */ Loading
libs/surfaceflinger_client/SharedBufferStack.cpp +46 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,14 @@ status_t SharedBufferStack::setCrop(int buffer, const Rect& crop) return NO_ERROR; } status_t SharedBufferStack::setTransform(int buffer, uint8_t transform) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) return BAD_INDEX; buffers[buffer].transform = transform; return NO_ERROR; } status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty) { if (uint32_t(buffer) >= NUM_BUFFER_MAX) Loading Loading @@ -137,6 +145,26 @@ Region SharedBufferStack::getDirtyRegion(int buffer) const return res; } Rect SharedBufferStack::getCrop(int buffer) const { Rect res(-1, -1); if (uint32_t(buffer) >= NUM_BUFFER_MAX) return res; res.left = buffers[buffer].crop.l; res.top = buffers[buffer].crop.t; res.right = buffers[buffer].crop.r; res.bottom = buffers[buffer].crop.b; return res; } uint32_t SharedBufferStack::getTransform(int buffer) const { if (uint32_t(buffer) >= NUM_BUFFER_MAX) return 0; return buffers[buffer].transform; } // ---------------------------------------------------------------------------- SharedBufferBase::SharedBufferBase(SharedClient* sharedClient, Loading Loading @@ -433,6 +461,12 @@ status_t SharedBufferClient::setCrop(int buf, const Rect& crop) return stack.setCrop(buf, crop); } status_t SharedBufferClient::setTransform(int buf, uint32_t transform) { SharedBufferStack& stack( *mSharedStack ); return stack.setTransform(buf, uint8_t(transform)); } status_t SharedBufferClient::setDirtyRegion(int buf, const Region& reg) { SharedBufferStack& stack( *mSharedStack ); Loading Loading @@ -549,6 +583,18 @@ Region SharedBufferServer::getDirtyRegion(int buf) const return stack.getDirtyRegion(buf); } Rect SharedBufferServer::getCrop(int buf) const { SharedBufferStack& stack( *mSharedStack ); return stack.getCrop(buf); } uint32_t SharedBufferServer::getTransform(int buf) const { SharedBufferStack& stack( *mSharedStack ); return stack.getTransform(buf); } /* * NOTE: this is not thread-safe on the server-side, meaning * 'head' cannot move during this operation. The client-side Loading
libs/surfaceflinger_client/Surface.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -422,8 +422,10 @@ void Surface::init() const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; const_cast<uint32_t&>(ANativeWindow::flags) = 0; mNextBufferTransform = 0; mConnected = 0; mSwapRectangle.makeInvalid(); mNextBufferCrop = Rect(0,0); // two buffers by default mBuffers.setCapacity(2); mBuffers.insertAt(0, 2); Loading Loading @@ -631,6 +633,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) } int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer)); mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform); mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop); mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion); err = mSharedBufferClient->queue(bufIdx); Loading Loading @@ -685,6 +688,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: res = dispatch_set_buffers_geometry( args ); break; case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: res = dispatch_set_buffers_transform( args ); break; default: res = NAME_NOT_FOUND; break; Loading Loading @@ -719,6 +725,11 @@ int Surface::dispatch_set_buffers_geometry(va_list args) { return setBuffersGeometry(w, h, f); } int Surface::dispatch_set_buffers_transform(va_list args) { int transform = va_arg(args, int); return setBuffersTransform(transform); } void Surface::setUsage(uint32_t reqUsage) { Mutex::Autolock _l(mSurfaceLock); Loading Loading @@ -765,6 +776,10 @@ int Surface::disconnect(int api) int Surface::crop(Rect const* rect) { // empty/invalid rects are not allowed if (rect->isEmpty()) return BAD_VALUE; Mutex::Autolock _l(mSurfaceLock); // TODO: validate rect size mNextBufferCrop = *rect; Loading Loading @@ -804,6 +819,13 @@ int Surface::setBuffersGeometry(int w, int h, int format) return NO_ERROR; } int Surface::setBuffersTransform(int transform) { Mutex::Autolock _l(mSurfaceLock); mNextBufferTransform = transform; return NO_ERROR; } // ---------------------------------------------------------------------------- int Surface::getConnectedApi() const Loading