From e96aa3e859cb747e241dfa2999fcd142a688ed57 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 19 Aug 2010 17:01:19 -0700 Subject: fix [2931513] Add support for setting the orientation of an ANativeWindow Also implement support for cropping. Change-Id: Iba5888dd242bf2feaac9e9ce26e404c1f404c280 --- libs/surfaceflinger_client/SharedBufferStack.cpp | 46 ++++++++++++++++++++++++ libs/surfaceflinger_client/Surface.cpp | 22 ++++++++++++ 2 files changed, 68 insertions(+) (limited to 'libs') diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp index 156a7db..4ad9f86 100644 --- a/libs/surfaceflinger_client/SharedBufferStack.cpp +++ b/libs/surfaceflinger_client/SharedBufferStack.cpp @@ -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) @@ -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, @@ -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 ); @@ -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 diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp index 5ab72cd..cb76091 100644 --- a/libs/surfaceflinger_client/Surface.cpp +++ b/libs/surfaceflinger_client/Surface.cpp @@ -422,8 +422,10 @@ void Surface::init() const_cast(ANativeWindow::maxSwapInterval) = 1; const_cast(ANativeWindow::flags) = 0; + mNextBufferTransform = 0; mConnected = 0; mSwapRectangle.makeInvalid(); + mNextBufferCrop = Rect(0,0); // two buffers by default mBuffers.setCapacity(2); mBuffers.insertAt(0, 2); @@ -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); @@ -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; @@ -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); @@ -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; @@ -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 -- cgit v1.1