summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gui/SurfaceComposerClient.h2
-rw-r--r--include/gui/SurfaceControl.h5
-rw-r--r--include/private/gui/LayerState.h7
-rw-r--r--libs/gui/LayerState.cpp2
-rw-r--r--libs/gui/SurfaceComposerClient.cpp35
-rw-r--r--libs/gui/SurfaceControl.cpp6
-rw-r--r--services/surfaceflinger/Layer.cpp34
-rw-r--r--services/surfaceflinger/Layer.h8
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp5
-rw-r--r--services/surfaceflinger/SurfaceFlinger_hwc1.cpp5
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;
}