diff options
| -rw-r--r-- | include/gui/SurfaceComposerClient.h | 2 | ||||
| -rw-r--r-- | include/gui/SurfaceControl.h | 5 | ||||
| -rw-r--r-- | include/private/gui/LayerState.h | 7 | ||||
| -rw-r--r-- | libs/gui/LayerState.cpp | 2 | ||||
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 35 | ||||
| -rw-r--r-- | libs/gui/SurfaceControl.cpp | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 34 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger_hwc1.cpp | 5 |
10 files changed, 101 insertions, 8 deletions
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index 9161dbb442..73f923c237 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -138,6 +138,8 @@ public: status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack); status_t deferTransactionUntil(const sp<IBinder>& id, const sp<IBinder>& handle, uint64_t frameNumber); + status_t setOverrideScalingMode(const sp<IBinder>& id, + int32_t overrideScalingMode); status_t destroySurface(const sp<IBinder>& id); status_t clearLayerFrameStats(const sp<IBinder>& token) const; diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h index 35644db12b..bedebb6051 100644 --- a/include/gui/SurfaceControl.h +++ b/include/gui/SurfaceControl.h @@ -77,6 +77,11 @@ public: // identified by handle reaches the given frameNumber status_t deferTransactionUntil(sp<IBinder> handle, uint64_t frameNumber); + // Set an override scaling mode as documented in <system/window.h> + // the override scaling mode will take precedence over any client + // specified scaling mode. -1 will clear the override scaling mode. + status_t setOverrideScalingMode(int32_t overrideScalingMode); + static status_t writeSurfaceToParcel( const sp<SurfaceControl>& control, Parcel* parcel); diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h index 078720a87e..92d31d1012 100644 --- a/include/private/gui/LayerState.h +++ b/include/private/gui/LayerState.h @@ -53,7 +53,8 @@ struct layer_state_t { eLayerStackChanged = 0x00000080, eCropChanged = 0x00000100, eDeferTransaction = 0x00000200, - eFinalCropChanged = 0x00000400 + eFinalCropChanged = 0x00000400, + eOverrideScalingModeChanged = 0x00000800 }; layer_state_t() @@ -61,7 +62,8 @@ struct layer_state_t { x(0), y(0), z(0), w(0), h(0), layerStack(0), alpha(0), flags(0), mask(0), reserved(0), crop(Rect::INVALID_RECT), - finalCrop(Rect::INVALID_RECT), frameNumber(0) + finalCrop(Rect::INVALID_RECT), frameNumber(0), + overrideScalingMode(-1) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; @@ -93,6 +95,7 @@ struct layer_state_t { Rect finalCrop; sp<IBinder> handle; uint64_t frameNumber; + int32_t overrideScalingMode; // non POD must be last. see write/read Region transparentRegion; }; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e43342e34a..d1c576e4c5 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -41,6 +41,7 @@ status_t layer_state_t::write(Parcel& output) const output.write(finalCrop); output.writeStrongBinder(handle); output.writeUint64(frameNumber); + output.writeInt32(overrideScalingMode); output.write(transparentRegion); return NO_ERROR; } @@ -68,6 +69,7 @@ status_t layer_state_t::read(const Parcel& input) input.read(finalCrop); handle = input.readStrongBinder(); frameNumber = input.readUint64(); + overrideScalingMode = input.readInt32(); input.read(transparentRegion); return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 418892a1c3..e33cc37b24 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -163,6 +163,8 @@ public: status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, const sp<IBinder>& handle, uint64_t frameNumber); + status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client, + const sp<IBinder>& id, int32_t overrideScalingMode); void setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); @@ -414,6 +416,33 @@ status_t Composer::deferTransactionUntil( return NO_ERROR; } +status_t Composer::setOverrideScalingMode( + const sp<SurfaceComposerClient>& client, + const sp<IBinder>& id, int32_t overrideScalingMode) { + Mutex::Autolock lock(mLock); + layer_state_t* s = getLayerStateLocked(client, id); + if (!s) { + return BAD_INDEX; + } + + switch (overrideScalingMode) { + case NATIVE_WINDOW_SCALING_MODE_FREEZE: + case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: + case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: + case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: + case -1: + break; + default: + ALOGE("unknown scaling mode: %d", + overrideScalingMode); + return BAD_VALUE; + } + + s->what |= layer_state_t::eOverrideScalingModeChanged; + s->overrideScalingMode = overrideScalingMode; + return NO_ERROR; +} + // --------------------------------------------------------------------------- DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) { @@ -650,6 +679,12 @@ status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id, return getComposer().deferTransactionUntil(this, id, handle, frameNumber); } +status_t SurfaceComposerClient::setOverrideScalingMode( + const sp<IBinder>& id, int32_t overrideScalingMode) { + return getComposer().setOverrideScalingMode( + this, id, overrideScalingMode); +} + // ---------------------------------------------------------------------------- void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token, diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 184de71986..314d83a209 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -165,6 +165,12 @@ status_t SurfaceControl::deferTransactionUntil(sp<IBinder> handle, return mClient->deferTransactionUntil(mHandle, handle, frameNumber); } +status_t SurfaceControl::setOverrideScalingMode(int32_t overrideScalingMode) { + status_t err = validate(); + if (err < 0) return err; + return mClient->setOverrideScalingMode(mHandle, overrideScalingMode); +} + status_t SurfaceControl::clearLayerFrameStats() const { status_t err = validate(); if (err < 0) return err; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 90ab70d33f..1803ee5d29 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -75,6 +75,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, mSidebandStreamChanged(false), mCurrentTransform(0), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), + mOverrideScalingMode(-1), mCurrentOpacity(true), mCurrentFrameNumber(0), mRefreshPending(false), @@ -1244,7 +1245,7 @@ bool Layer::isProtected() const } bool Layer::isFixedSize() const { - return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; + return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE; } bool Layer::isCropped() const { @@ -1403,7 +1404,8 @@ uint32_t Layer::doTransaction(uint32_t flags) { " requested={ wh={%4u,%4u} }}\n" " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" " requested={ wh={%4u,%4u} }}\n", - this, getName().string(), mCurrentTransform, mCurrentScalingMode, + this, getName().string(), mCurrentTransform, + getEffectiveScalingMode(), c.active.w, c.active.h, c.crop.left, c.crop.top, @@ -1580,6 +1582,20 @@ bool Layer::setFinalCrop(const Rect& crop) { return true; } +bool Layer::setOverrideScalingMode(int32_t scalingMode) { + if (scalingMode == mOverrideScalingMode) + return false; + mOverrideScalingMode = scalingMode; + return true; +} + +uint32_t Layer::getEffectiveScalingMode() const { + if (mOverrideScalingMode >= 0) { + return mOverrideScalingMode; + } + return mCurrentScalingMode; +} + bool Layer::setLayerStack(uint32_t layerStack) { if (mCurrentState.layerStack == layerStack) return false; @@ -1738,14 +1754,17 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) bool& recomputeVisibleRegions; bool stickyTransformSet; const char* name; + int32_t overrideScalingMode; Reject(Layer::State& front, Layer::State& current, bool& recomputeVisibleRegions, bool stickySet, - const char* name) + const char* name, + int32_t overrideScalingMode) : front(front), current(current), recomputeVisibleRegions(recomputeVisibleRegions), stickyTransformSet(stickySet), - name(name) { + name(name), + overrideScalingMode(overrideScalingMode) { } virtual bool reject(const sp<GraphicBuffer>& buf, @@ -1763,7 +1782,9 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) swap(bufWidth, bufHeight); } - bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; + int actualScalingMode = overrideScalingMode >= 0 ? + overrideScalingMode : item.mScalingMode; + bool isFixedSize = actualScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; if (front.active != front.requested) { if (isFixedSize || @@ -1839,7 +1860,8 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) }; Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, - getProducerStickyTransform() != 0, mName.string()); + getProducerStickyTransform() != 0, mName.string(), + mOverrideScalingMode); // Check all of our local sync points to ensure that all transactions diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c6236720d3..7d085a479a 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -160,6 +160,7 @@ public: bool setFinalCrop(const Rect& crop); bool setLayerStack(uint32_t layerStack); void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber); + bool setOverrideScalingMode(int32_t overrideScalingMode); // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with @@ -502,6 +503,11 @@ private: void pushPendingState(); void popPendingState(State* stateToCommit); bool applyPendingStates(State* stateToCommit); + + // Returns mCurrentScaling mode (originating from the + // Client) or mOverrideScalingMode mode (originating from + // the Surface Controller) if set. + uint32_t getEffectiveScalingMode() const; public: void notifyAvailableFrames(); private: @@ -536,6 +542,8 @@ private: Rect mCurrentCrop; uint32_t mCurrentTransform; uint32_t mCurrentScalingMode; + // We encode unset as -1. + int32_t mOverrideScalingMode; bool mCurrentOpacity; std::atomic<uint64_t> mCurrentFrameNumber; bool mRefreshPending; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1f85bee079..efa32a7089 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2291,6 +2291,11 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } + if (what & layer_state_t::eOverrideScalingModeChanged) { + layer->setOverrideScalingMode(s.overrideScalingMode); + // We don't trigger a traversal here because if no other state is + // changed, we don't want this to cause any more work + } } return flags; } diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp index e9b3d99101..bc20bbce4a 100644 --- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp +++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp @@ -2316,6 +2316,11 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } + if (what & layer_state_t::eOverrideScalingModeChanged) { + layer->setOverrideScalingMode(s.overrideScalingMode); + // We don't trigger a traversal here because if no other state is + // changed, we don't want this to cause any more work + } } return flags; } |