From f58c14b3d51f2face21c9759149b5c9412bcafd5 Mon Sep 17 00:00:00 2001 From: Marissa Wall Date: Tue, 24 Jul 2018 10:50:43 -0700 Subject: blast: Append "_legacy" to old buffer state values As we move from BufferQueueLayer to BufferStateLayer, some layer state fields are used by both layer types and some are used exclusively by one type of layer. Append "_legacy" to all fields that are NOT used by BufferStateLayer. Bug: 80477568 Test: Transaction_test.cpp Change-Id: Id8bf27f5b68c00592136e4336442a5d388f35779 --- libs/gui/LayerState.cpp | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 01acc2de20..0414a486e6 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -37,13 +37,13 @@ status_t layer_state_t::write(Parcel& output) const output.writeUint32(mask); *reinterpret_cast( output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix; - output.write(crop); - output.write(finalCrop); - output.writeStrongBinder(barrierHandle); + output.write(crop_legacy); + output.write(finalCrop_legacy); + output.writeStrongBinder(barrierHandle_legacy); output.writeStrongBinder(reparentHandle); - output.writeUint64(frameNumber); + output.writeUint64(frameNumber_legacy); output.writeInt32(overrideScalingMode); - output.writeStrongBinder(IInterface::asBinder(barrierGbp)); + output.writeStrongBinder(IInterface::asBinder(barrierGbp_legacy)); output.writeStrongBinder(relativeLayerHandle); output.writeStrongBinder(parentHandleForChild); output.writeFloat(color.r); @@ -72,14 +72,13 @@ status_t layer_state_t::read(const Parcel& input) } else { return BAD_VALUE; } - input.read(crop); - input.read(finalCrop); - barrierHandle = input.readStrongBinder(); + input.read(crop_legacy); + input.read(finalCrop_legacy); + barrierHandle_legacy = input.readStrongBinder(); reparentHandle = input.readStrongBinder(); - frameNumber = input.readUint64(); + frameNumber_legacy = input.readUint64(); overrideScalingMode = input.readInt32(); - barrierGbp = - interface_cast(input.readStrongBinder()); + barrierGbp_legacy = interface_cast(input.readStrongBinder()); relativeLayerHandle = input.readStrongBinder(); parentHandleForChild = input.readStrongBinder(); color.r = input.readFloat(); @@ -194,19 +193,19 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eLayerStackChanged; layerStack = other.layerStack; } - if (other.what & eCropChanged) { - what |= eCropChanged; - crop = other.crop; + if (other.what & eCropChanged_legacy) { + what |= eCropChanged_legacy; + crop_legacy = other.crop_legacy; } - if (other.what & eDeferTransaction) { - what |= eDeferTransaction; - barrierHandle = other.barrierHandle; - barrierGbp = other.barrierGbp; - frameNumber = other.frameNumber; + if (other.what & eDeferTransaction_legacy) { + what |= eDeferTransaction_legacy; + barrierHandle_legacy = other.barrierHandle_legacy; + barrierGbp_legacy = other.barrierGbp_legacy; + frameNumber_legacy = other.frameNumber_legacy; } - if (other.what & eFinalCropChanged) { - what |= eFinalCropChanged; - finalCrop = other.finalCrop; + if (other.what & eFinalCropChanged_legacy) { + what |= eFinalCropChanged_legacy; + finalCrop_legacy = other.finalCrop_legacy; } if (other.what & eOverrideScalingModeChanged) { what |= eOverrideScalingModeChanged; -- cgit v1.2.3-59-g8ed1b From 61c58627dd748baa699bab62e80a7972f2030f60 Mon Sep 17 00:00:00 2001 From: Marissa Wall Date: Wed, 18 Jul 2018 10:12:20 -0700 Subject: blast: BufferStateLayer Adds the initial foundation for supporting buffers on transactions as well as the other metadata that had been passed over BufferQueue. Bug: 80477568 Test: Transaction_test.cpp Change-Id: I61e44462c66c1a912adbabf62015e66bde44c216 --- libs/gui/LayerState.cpp | 85 ++ libs/gui/SurfaceComposerClient.cpp | 121 +++ libs/gui/include/gui/ISurfaceComposerClient.h | 3 +- libs/gui/include/gui/LayerState.h | 33 +- libs/gui/include/gui/SurfaceComposerClient.h | 14 + services/surfaceflinger/Android.bp | 1 + services/surfaceflinger/BufferLayer.cpp | 19 +- services/surfaceflinger/BufferLayer.h | 9 +- services/surfaceflinger/BufferQueueLayer.cpp | 4 +- services/surfaceflinger/BufferQueueLayer.h | 4 +- services/surfaceflinger/BufferStateLayer.cpp | 545 ++++++++++ services/surfaceflinger/BufferStateLayer.h | 142 +++ services/surfaceflinger/ColorLayer.cpp | 4 +- services/surfaceflinger/ColorLayer.h | 4 +- services/surfaceflinger/ContainerLayer.cpp | 4 +- services/surfaceflinger/ContainerLayer.h | 4 +- services/surfaceflinger/Layer.cpp | 184 ++-- services/surfaceflinger/Layer.h | 103 +- services/surfaceflinger/LayerBE.h | 1 + services/surfaceflinger/LayerRejecter.cpp | 3 +- services/surfaceflinger/SurfaceFlinger.cpp | 61 +- services/surfaceflinger/SurfaceFlinger.h | 5 + services/surfaceflinger/SurfaceInterceptor.cpp | 1 + services/surfaceflinger/tests/Transaction_test.cpp | 1038 ++++++++++++++++---- 24 files changed, 2071 insertions(+), 321 deletions(-) create mode 100644 services/surfaceflinger/BufferStateLayer.cpp create mode 100644 services/surfaceflinger/BufferStateLayer.h (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 0414a486e6..931c446275 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -50,6 +50,32 @@ status_t layer_state_t::write(Parcel& output) const output.writeFloat(color.g); output.writeFloat(color.b); output.write(transparentRegion); + output.writeUint32(transform); + output.writeBool(transformToDisplayInverse); + output.write(crop); + if (buffer) { + output.writeBool(true); + output.write(*buffer); + } else { + output.writeBool(false); + } + if (acquireFence) { + output.writeBool(true); + output.write(*acquireFence); + } else { + output.writeBool(false); + } + output.writeUint32(static_cast(dataspace)); + output.write(hdrMetadata); + output.write(surfaceDamageRegion); + output.writeInt32(api); + if (sidebandStream) { + output.writeBool(true); + output.writeNativeHandle(sidebandStream->handle()); + } else { + output.writeBool(false); + } + return NO_ERROR; } @@ -85,6 +111,25 @@ status_t layer_state_t::read(const Parcel& input) color.g = input.readFloat(); color.b = input.readFloat(); input.read(transparentRegion); + transform = input.readUint32(); + transformToDisplayInverse = input.readBool(); + input.read(crop); + buffer = new GraphicBuffer(); + if (input.readBool()) { + input.read(*buffer); + } + acquireFence = new Fence(); + if (input.readBool()) { + input.read(*acquireFence); + } + dataspace = static_cast(input.readUint32()); + input.read(hdrMetadata); + input.read(surfaceDamageRegion); + api = input.readInt32(); + if (input.readBool()) { + sidebandStream = NativeHandle::create(input.readNativeHandle(), true); + } + return NO_ERROR; } @@ -233,6 +278,46 @@ void layer_state_t::merge(const layer_state_t& other) { if (other.what & eDestroySurface) { what |= eDestroySurface; } + if (other.what & eTransformChanged) { + what |= eTransformChanged; + transform = other.transform; + } + if (other.what & eTransformToDisplayInverseChanged) { + what |= eTransformToDisplayInverseChanged; + transformToDisplayInverse = other.transformToDisplayInverse; + } + if (other.what & eCropChanged) { + what |= eCropChanged; + crop = other.crop; + } + if (other.what & eBufferChanged) { + what |= eBufferChanged; + buffer = other.buffer; + } + if (other.what & eAcquireFenceChanged) { + what |= eAcquireFenceChanged; + acquireFence = other.acquireFence; + } + if (other.what & eDataspaceChanged) { + what |= eDataspaceChanged; + dataspace = other.dataspace; + } + if (other.what & eHdrMetadataChanged) { + what |= eHdrMetadataChanged; + hdrMetadata = other.hdrMetadata; + } + if (other.what & eSurfaceDamageRegionChanged) { + what |= eSurfaceDamageRegionChanged; + surfaceDamageRegion = other.surfaceDamageRegion; + } + if (other.what & eApiChanged) { + what |= eApiChanged; + api = other.api; + } + if (other.what & eSidebandStreamChanged) { + what |= eSidebandStreamChanged; + sidebandStream = other.sidebandStream; + } } }; // namespace android diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 3ff0ec20ea..17cff546e0 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -437,6 +437,127 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColor return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTransform( + const sp& sc, uint32_t transform) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eTransformChanged; + s->transform = transform; + return *this; +} + +SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp& sc, + bool transformToDisplayInverse) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eTransformToDisplayInverseChanged; + s->transformToDisplayInverse = transformToDisplayInverse; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop( + const sp& sc, const Rect& crop) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eCropChanged; + s->crop = crop; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer( + const sp& sc, const sp& buffer) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eBufferChanged; + s->buffer = buffer; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAcquireFence( + const sp& sc, const sp& fence) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eAcquireFenceChanged; + s->acquireFence = fence; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDataspace( + const sp& sc, ui::Dataspace dataspace) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eDataspaceChanged; + s->dataspace = dataspace; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setHdrMetadata( + const sp& sc, const HdrMetadata& hdrMetadata) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eHdrMetadataChanged; + s->hdrMetadata = hdrMetadata; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSurfaceDamageRegion( + const sp& sc, const Region& surfaceDamageRegion) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eSurfaceDamageRegionChanged; + s->surfaceDamageRegion = surfaceDamageRegion; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApi( + const sp& sc, int32_t api) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eApiChanged; + s->api = api; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSidebandStream( + const sp& sc, const sp& sidebandStream) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eSidebandStreamChanged; + s->sidebandStream = sidebandStream; + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::detachChildren( const sp& sc) { layer_state_t* s = getLayerState(sc); diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h index 8dfc99a4b7..11261c307c 100644 --- a/libs/gui/include/gui/ISurfaceComposerClient.h +++ b/libs/gui/include/gui/ISurfaceComposerClient.h @@ -40,8 +40,9 @@ public: eProtectedByDRM = 0x00001000, eCursorWindow = 0x00002000, - eFXSurfaceNormal = 0x00000000, + eFXSurfaceBufferQueue = 0x00000000, eFXSurfaceColor = 0x00020000, + eFXSurfaceBufferState = 0x00040000, eFXSurfaceMask = 0x000F0000, }; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index b88b7fe118..098179864a 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -61,7 +62,17 @@ struct layer_state_t { eRelativeLayerChanged = 0x00008000, eReparent = 0x00010000, eColorChanged = 0x00020000, - eDestroySurface = 0x00040000 + eDestroySurface = 0x00040000, + eTransformChanged = 0x00100000, + eTransformToDisplayInverseChanged = 0x00200000, + eCropChanged = 0x00400000, + eBufferChanged = 0x00800000, + eAcquireFenceChanged = 0x01000000, + eDataspaceChanged = 0x02000000, + eHdrMetadataChanged = 0x04000000, + eSurfaceDamageRegionChanged = 0x08000000, + eApiChanged = 0x10000000, + eSidebandStreamChanged = 0x20000000, }; layer_state_t() @@ -79,9 +90,16 @@ struct layer_state_t { crop_legacy(Rect::INVALID_RECT), finalCrop_legacy(Rect::INVALID_RECT), frameNumber_legacy(0), - overrideScalingMode(-1) { + overrideScalingMode(-1), + transform(0), + transformToDisplayInverse(false), + crop(Rect::INVALID_RECT), + dataspace(ui::Dataspace::UNKNOWN), + surfaceDamageRegion(), + api(-1) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; + hdrMetadata.validTypes = 0; } void merge(const layer_state_t& other); @@ -124,6 +142,17 @@ struct layer_state_t { // non POD must be last. see write/read Region transparentRegion; + + uint32_t transform; + bool transformToDisplayInverse; + Rect crop; + sp buffer; + sp acquireFence; + ui::Dataspace dataspace; + HdrMetadata hdrMetadata; + Region surfaceDamageRegion; + int32_t api; + sp sidebandStream; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 278a642c91..4907866d0f 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -227,6 +227,20 @@ public: Transaction& setColor(const sp& sc, const half3& color); + Transaction& setTransform(const sp& sc, uint32_t transform); + Transaction& setTransformToDisplayInverse(const sp& sc, + bool transformToDisplayInverse); + Transaction& setCrop(const sp& sc, const Rect& crop); + Transaction& setBuffer(const sp& sc, const sp& buffer); + Transaction& setAcquireFence(const sp& sc, const sp& fence); + Transaction& setDataspace(const sp& sc, ui::Dataspace dataspace); + Transaction& setHdrMetadata(const sp& sc, const HdrMetadata& hdrMetadata); + Transaction& setSurfaceDamageRegion(const sp& sc, + const Region& surfaceDamageRegion); + Transaction& setApi(const sp& sc, int32_t api); + Transaction& setSidebandStream(const sp& sc, + const sp& sidebandStream); + // Detaches all child surfaces (and their children recursively) // from their SurfaceControl. // The child SurfaceControls will not throw exceptions or return errors, diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 0be1fd7d93..3fa1311ce9 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -92,6 +92,7 @@ filegroup { "BufferLayer.cpp", "BufferLayerConsumer.cpp", "BufferQueueLayer.cpp", + "BufferStateLayer.cpp", "Client.cpp", "ColorLayer.cpp", "ContainerLayer.cpp", diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 64842450fa..e7246665dd 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -136,7 +136,7 @@ static constexpr mat4 inverseOrientation(uint32_t transform) { * onDraw will draw the current layer onto the presentable buffer */ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, - bool useIdentityTransform) const { + bool useIdentityTransform) { ATRACE_CALL(); CompositionInfo& compositionInfo = getBE().compositionInfo; @@ -232,7 +232,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, engine.disableTexturing(); } -void BufferLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) const { +void BufferLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) { CompositionInfo& compositionInfo = getBE().compositionInfo; auto& engine(mFlinger->getRenderEngine()); @@ -518,7 +518,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // FIXME: postedRegion should be dirty & bounds // transform the dirty region to window-manager space - return getTransform().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h))); + return getTransform().transform(Region(Rect(getActiveWidth(s), getActiveHeight(s)))); } // transaction @@ -641,9 +641,10 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT Transform t = getTransform(); Rect win = bounds; - if (!s.finalCrop_legacy.isEmpty()) { + Rect finalCrop = getFinalCrop(s); + if (!finalCrop.isEmpty()) { win = t.transform(win); - if (!win.intersect(s.finalCrop_legacy, &win)) { + if (!win.intersect(finalCrop, &win)) { win.clear(); } win = t.inverse().transform(win); @@ -652,10 +653,10 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT } } - float left = float(win.left) / float(s.active_legacy.w); - float top = float(win.top) / float(s.active_legacy.h); - float right = float(win.right) / float(s.active_legacy.w); - float bottom = float(win.bottom) / float(s.active_legacy.h); + float left = float(win.left) / float(getActiveWidth(s)); + float top = float(win.top) / float(getActiveHeight(s)); + float right = float(win.right) / float(getActiveWidth(s)); + float bottom = float(win.bottom) / float(getActiveHeight(s)); // TODO: we probably want to generate the texture coords with the mesh // here we assume that we only have 4 vertices diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 6ffcff4a2a..13f4e83b44 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -78,8 +78,8 @@ public: // onDraw - draws the surface. void onDraw(const RenderArea& renderArea, const Region& clip, - bool useIdentityTransform) const override; - void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const; + bool useIdentityTransform) override; + void drawNow(const RenderArea& renderArea, bool useIdentityTransform); bool isHdrY410() const override; @@ -102,7 +102,6 @@ public: bool hasReadyFrame() const override; -private: // Returns the current scaling mode, unless mOverrideScalingMode // is set, in which case, it returns mOverrideScalingMode uint32_t getEffectiveScalingMode() const override; @@ -117,7 +116,7 @@ private: virtual nsecs_t getDesiredPresentTime() = 0; virtual std::shared_ptr getCurrentFenceTime() const = 0; - virtual void getDrawingTransformMatrix(float matrix[16]) const = 0; + virtual void getDrawingTransformMatrix(float *matrix) = 0; virtual uint32_t getDrawingTransform() const = 0; virtual ui::Dataspace getDrawingDataSpace() const = 0; virtual Rect getDrawingCrop() const = 0; @@ -136,7 +135,7 @@ private: virtual bool hasDrawingBuffer() const = 0; - virtual void setFilteringEnabled(bool enabled) const = 0; + virtual void setFilteringEnabled(bool enabled) = 0; virtual status_t bindTextureImage() const = 0; virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) = 0; diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index 1bf9cf275b..0913de419e 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -152,7 +152,7 @@ std::shared_ptr BufferQueueLayer::getCurrentFenceTime() const { return mConsumer->getCurrentFenceTime(); } -void BufferQueueLayer::getDrawingTransformMatrix(float matrix[16]) const { +void BufferQueueLayer::getDrawingTransformMatrix(float *matrix) { return mConsumer->getTransformMatrix(matrix); } @@ -228,7 +228,7 @@ bool BufferQueueLayer::hasDrawingBuffer() const { return mQueuedFrames > 0; } -void BufferQueueLayer::setFilteringEnabled(bool enabled) const { +void BufferQueueLayer::setFilteringEnabled(bool enabled) { return mConsumer->setFilteringEnabled(enabled); } diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index 7454e2058a..579ed81f7e 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -68,7 +68,7 @@ private: nsecs_t getDesiredPresentTime() override; std::shared_ptr getCurrentFenceTime() const override; - void getDrawingTransformMatrix(float matrix[16]) const override; + void getDrawingTransformMatrix(float *matrix) override; uint32_t getDrawingTransform() const override; ui::Dataspace getDrawingDataSpace() const override; Rect getDrawingCrop() const override; @@ -87,7 +87,7 @@ private: bool hasDrawingBuffer() const override; - void setFilteringEnabled(bool enabled) const override; + void setFilteringEnabled(bool enabled) override; status_t bindTextureImage() const override; status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) override; diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp new file mode 100644 index 0000000000..2e411f1ab8 --- /dev/null +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -0,0 +1,545 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#undef LOG_TAG +#define LOG_TAG "BufferStateLayer" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include "BufferStateLayer.h" +#include "RenderEngine/Image.h" +#include "clz.h" + +#include + +namespace android { + +static const std::array IDENTITY_MATRIX{1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + +BufferStateLayer::BufferStateLayer(SurfaceFlinger* flinger, const sp& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags) + : BufferLayer(flinger, client, name, w, h, flags), + mSidebandStreamChanged(false), + mFrameNumber(0) { + mTransformMatrix = IDENTITY_MATRIX; +} + +// ----------------------------------------------------------------------- +// Interface implementation for Layer +// ----------------------------------------------------------------------- +void BufferStateLayer::onLayerDisplayed(const sp& /*releaseFence*/) { + // TODO(marissaw): send the release fence back to buffer owner + return; +} + +void BufferStateLayer::setTransformHint(uint32_t /*orientation*/) const { + // TODO(marissaw): send the transform hint to buffer owner + return; +} + +void BufferStateLayer::releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) { + // TODO(marissaw): use this to signal the buffer owner + return; +} + +bool BufferStateLayer::shouldPresentNow(const DispSync& /*dispSync*/) const { + if (getSidebandStreamChanged() || getAutoRefresh()) { + return true; + } + + return hasDrawingBuffer(); +} + +bool BufferStateLayer::getTransformToDisplayInverse() const { + return mCurrentState.transformToDisplayInverse; +} + +void BufferStateLayer::pushPendingState() { + if (!mCurrentState.modified) { + return; + } + mPendingStates.push_back(mCurrentState); + ATRACE_INT(mTransactionName.string(), mPendingStates.size()); +} + +bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) { + const bool stateUpdateAvailable = !mPendingStates.empty(); + while (!mPendingStates.empty()) { + popPendingState(stateToCommit); + } + mCurrentState.modified = false; + return stateUpdateAvailable; +} + +Rect BufferStateLayer::getCrop(const Layer::State& s) const { + return (getEffectiveScalingMode() == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) + ? GLConsumer::scaleDownCrop(s.crop, s.active.w, s.active.h) + : s.crop; +} + +bool BufferStateLayer::setTransform(uint32_t transform) { + if (mCurrentState.transform == transform) return false; + mCurrentState.sequence++; + mCurrentState.transform = transform; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) { + if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false; + mCurrentState.sequence++; + mCurrentState.transformToDisplayInverse = transformToDisplayInverse; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setCrop(const Rect& crop) { + if (mCurrentState.crop == crop) return false; + mCurrentState.sequence++; + mCurrentState.crop = crop; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setBuffer(sp buffer) { + mCurrentState.sequence++; + mCurrentState.buffer = buffer; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setAcquireFence(const sp& fence) { + mCurrentState.acquireFence = fence; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) { + if (mCurrentState.dataspace == dataspace) return false; + mCurrentState.sequence++; + mCurrentState.dataspace = dataspace; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) { + if (mCurrentState.hdrMetadata == hdrMetadata) return false; + mCurrentState.sequence++; + mCurrentState.hdrMetadata = hdrMetadata; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) { + mCurrentState.sequence++; + mCurrentState.surfaceDamageRegion = surfaceDamage; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setApi(int32_t api) { + if (mCurrentState.api == api) return false; + mCurrentState.sequence++; + mCurrentState.api = api; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setSidebandStream(const sp& sidebandStream) { + if (mCurrentState.sidebandStream == sidebandStream) return false; + mCurrentState.sequence++; + mCurrentState.sidebandStream = sidebandStream; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + + if (!mSidebandStreamChanged.exchange(true)) { + // mSidebandStreamChanged was false + mFlinger->signalLayerUpdate(); + } + return true; +} + +bool BufferStateLayer::setSize(uint32_t w, uint32_t h) { + if (mCurrentState.active.w == w && mCurrentState.active.h == h) return false; + mCurrentState.active.w = w; + mCurrentState.active.h = h; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setPosition(float x, float y, bool /*immediate*/) { + if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y) + return false; + + mCurrentState.active.transform.set(x, y); + + mCurrentState.sequence++; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) { + mCurrentState.transparentRegionHint = transparent; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix, + bool allowNonRectPreservingTransforms) { + Transform t; + t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); + + if (!allowNonRectPreservingTransforms && !t.preserveRects()) { + ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored"); + return false; + } + + mCurrentState.sequence++; + mCurrentState.active.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} +// ----------------------------------------------------------------------- + +// ----------------------------------------------------------------------- +// Interface implementation for BufferLayer +// ----------------------------------------------------------------------- +bool BufferStateLayer::fenceHasSignaled() const { + if (latchUnsignaledBuffers()) { + return true; + } + + return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled; +} + +nsecs_t BufferStateLayer::getDesiredPresentTime() { + // TODO(marissaw): support an equivalent to desiredPresentTime for timestats metrics + return 0; +} + +std::shared_ptr BufferStateLayer::getCurrentFenceTime() const { + return std::make_shared(getDrawingState().acquireFence); +} + +void BufferStateLayer::getDrawingTransformMatrix(float *matrix) { + std::copy(std::begin(mTransformMatrix), std::end(mTransformMatrix), matrix); +} + +uint32_t BufferStateLayer::getDrawingTransform() const { + return getDrawingState().transform; +} + +ui::Dataspace BufferStateLayer::getDrawingDataSpace() const { + return getDrawingState().dataspace; +} + +Rect BufferStateLayer::getDrawingCrop() const { + return Rect::INVALID_RECT; +} + +uint32_t BufferStateLayer::getDrawingScalingMode() const { + return NATIVE_WINDOW_SCALING_MODE_FREEZE; +} + +Region BufferStateLayer::getDrawingSurfaceDamage() const { + return getDrawingState().surfaceDamageRegion; +} + +const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const { + return getDrawingState().hdrMetadata; +} + +int BufferStateLayer::getDrawingApi() const { + return getDrawingState().api; +} + +PixelFormat BufferStateLayer::getPixelFormat() const { + return mActiveBuffer->format; +} + +uint64_t BufferStateLayer::getFrameNumber() const { + return mFrameNumber; +} + +bool BufferStateLayer::getAutoRefresh() const { + // TODO(marissaw): support shared buffer mode + return false; +} + +bool BufferStateLayer::getSidebandStreamChanged() const { + return mSidebandStreamChanged.load(); +} + +std::optional BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) { + if (mSidebandStreamChanged.exchange(false)) { + const State& s(getDrawingState()); + // mSidebandStreamChanged was true + // replicated in LayerBE until FE/BE is ready to be synchronized + getBE().compositionInfo.hwc.sidebandStream = s.sidebandStream; + if (getBE().compositionInfo.hwc.sidebandStream != nullptr) { + setTransactionFlags(eTransactionNeeded); + mFlinger->setTransactionFlags(eTraversalNeeded); + } + recomputeVisibleRegions = true; + + return getTransform().transform(Region(Rect(s.active.w, s.active.h))); + } + return {}; +} + +bool BufferStateLayer::hasDrawingBuffer() const { + return getDrawingState().buffer != nullptr; +} + +void BufferStateLayer::setFilteringEnabled(bool enabled) { + GLConsumer::computeTransformMatrix(mTransformMatrix.data(), mActiveBuffer, mCurrentCrop, + mCurrentTransform, enabled); +} + +status_t BufferStateLayer::bindTextureImage() const { + const State& s(getDrawingState()); + auto& engine(mFlinger->getRenderEngine()); + + if (!engine.isCurrent()) { + ALOGE("RenderEngine is not current"); + return INVALID_OPERATION; + } + + engine.checkErrors(); + + if (!mTextureImage) { + ALOGE("no currently-bound texture"); + engine.bindExternalTextureImage(mTextureName, *engine.createImage()); + return NO_INIT; + } + + bool created = + mTextureImage->setNativeWindowBuffer(s.buffer->getNativeBuffer(), + s.buffer->getUsage() & GRALLOC_USAGE_PROTECTED); + if (!created) { + ALOGE("Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d", + s.buffer->getWidth(), s.buffer->getHeight(), s.buffer->getStride(), + s.buffer->getUsage(), s.buffer->getPixelFormat()); + engine.bindExternalTextureImage(mTextureName, *engine.createImage()); + return NO_INIT; + } + + engine.bindExternalTextureImage(mTextureName, *mTextureImage); + + // Wait for the new buffer to be ready. + if (s.acquireFence->isValid()) { + if (SyncFeatures::getInstance().useWaitSync()) { + base::unique_fd fenceFd(s.acquireFence->dup()); + if (fenceFd == -1) { + ALOGE("error dup'ing fence fd: %d", errno); + return -errno; + } + if (!engine.waitFence(std::move(fenceFd))) { + ALOGE("failed to wait on fence fd"); + return UNKNOWN_ERROR; + } + } else { + status_t err = s.acquireFence->waitForever("BufferStateLayer::bindTextureImage"); + if (err != NO_ERROR) { + ALOGE("error waiting for fence: %d", err); + return err; + } + } + } + + return NO_ERROR; +} + +status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime) { + const State& s(getDrawingState()); + + if (!s.buffer) { + return NO_ERROR; + } + + auto& engine(mFlinger->getRenderEngine()); + if (!engine.isCurrent()) { + ALOGE("RenderEngine is not current"); + return INVALID_OPERATION; + } + engine.checkErrors(); + + // TODO(marissaw): once buffers are cached, don't create a new image everytime + mTextureImage = engine.createImage(); + + // Reject if the layer is invalid + uint32_t bufferWidth = s.buffer->width; + uint32_t bufferHeight = s.buffer->height; + + if (s.transform & Transform::ROT_90) { + swap(bufferWidth, bufferHeight); + } + + if (s.transformToDisplayInverse) { + uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform(); + if (invTransform & Transform::ROT_90) { + swap(bufferWidth, bufferHeight); + } + } + + if (mOverrideScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE && + (s.active.w != bufferWidth || s.active.h != bufferHeight)) { + ALOGE("[%s] rejecting buffer: " + "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}", + mName.string(), bufferWidth, bufferHeight, s.active.w, s.active.h); + mTimeStats.removeTimeRecord(getName().c_str(), getFrameNumber()); + return BAD_VALUE; + } + + // Handle sync fences + if (SyncFeatures::getInstance().useNativeFenceSync()) { + base::unique_fd fenceFd = engine.flush(); + if (fenceFd == -1) { + ALOGE("failed to flush RenderEngine"); + mTimeStats.clearLayerRecord(getName().c_str()); + return UNKNOWN_ERROR; + } + + sp fence(new Fence(std::move(fenceFd))); + + // Check status of fences first because merging is expensive. + // Merging an invalid fence with any other fence results in an + // invalid fence. + auto currentStatus = s.acquireFence->getStatus(); + if (currentStatus == Fence::Status::Invalid) { + ALOGE("Existing fence has invalid state"); + mTimeStats.clearLayerRecord(getName().c_str()); + return BAD_VALUE; + } + + auto incomingStatus = fence->getStatus(); + if (incomingStatus == Fence::Status::Invalid) { + ALOGE("New fence has invalid state"); + mDrawingState.acquireFence = fence; + mTimeStats.clearLayerRecord(getName().c_str()); + return BAD_VALUE; + } + + // If both fences are signaled or both are unsignaled, we need to merge + // them to get an accurate timestamp. + if (currentStatus == incomingStatus) { + char fenceName[32] = {}; + snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber); + sp mergedFence = Fence::merge(fenceName, mDrawingState.acquireFence, fence); + if (!mergedFence.get()) { + ALOGE("failed to merge release fences"); + // synchronization is broken, the best we can do is hope fences + // signal in order so the new fence will act like a union + mDrawingState.acquireFence = fence; + mTimeStats.clearLayerRecord(getName().c_str()); + return BAD_VALUE; + } + mDrawingState.acquireFence = mergedFence; + } else if (incomingStatus == Fence::Status::Unsignaled) { + // If one fence has signaled and the other hasn't, the unsignaled + // fence will approximately correspond with the correct timestamp. + // There's a small race if both fences signal at about the same time + // and their statuses are retrieved with unfortunate timing. However, + // by this point, they will have both signaled and only the timestamp + // will be slightly off; any dependencies after this point will + // already have been met. + mDrawingState.acquireFence = fence; + } + } else { + // Bind the new buffer to the GL texture. + // + // Older devices require the "implicit" synchronization provided + // by glEGLImageTargetTexture2DOES, which this method calls. Newer + // devices will either call this in Layer::onDraw, or (if it's not + // a GL-composited layer) not at all. + status_t err = bindTextureImage(); + if (err != NO_ERROR) { + mTimeStats.clearLayerRecord(getName().c_str()); + return BAD_VALUE; + } + } + + // TODO(marissaw): properly support mTimeStats + const std::string layerName(getName().c_str()); + mTimeStats.setPostTime(getName().c_str(), getFrameNumber(), latchTime); + mTimeStats.setAcquireFence(layerName, getFrameNumber(), getCurrentFenceTime()); + mTimeStats.setLatchTime(layerName, getFrameNumber(), latchTime); + + return NO_ERROR; +} + +status_t BufferStateLayer::updateActiveBuffer() { + const State& s(getDrawingState()); + + if (s.buffer == nullptr) { + return BAD_VALUE; + } + + mActiveBuffer = s.buffer; + getBE().compositionInfo.mBuffer = mActiveBuffer; + getBE().compositionInfo.mBufferSlot = 0; + + return NO_ERROR; +} + +status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) { + // TODO(marissaw): support frame history events + mCurrentFrameNumber = mFrameNumber; + return NO_ERROR; +} + +void BufferStateLayer::setHwcLayerBuffer(const sp& display) { + const auto displayId = display->getId(); + auto& hwcInfo = getBE().mHwcLayers[displayId]; + auto& hwcLayer = hwcInfo.layer; + + const State& s(getDrawingState()); + + // TODO(marissaw): support more than one slot + uint32_t hwcSlot = 0; + + auto error = hwcLayer->setBuffer(hwcSlot, s.buffer, s.acquireFence); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), + s.buffer->handle, to_string(error).c_str(), static_cast(error)); + } + + mFrameNumber++; +} + +void BufferStateLayer::onFirstRef() { + if (const auto display = mFlinger->getDefaultDisplayDevice()) { + updateTransformHint(display); + } +} + +} // namespace android diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h new file mode 100644 index 0000000000..4d7396ef81 --- /dev/null +++ b/services/surfaceflinger/BufferStateLayer.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "RenderEngine/Image.h" +#include "RenderEngine/RenderEngine.h" + +#include "BufferLayer.h" +#include "Layer.h" + +#include +#include +#include + +namespace android { + +class BufferStateLayer : public BufferLayer { +public: + BufferStateLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, + uint32_t w, uint32_t h, uint32_t flags); + + // ----------------------------------------------------------------------- + // Interface implementation for Layer + // ----------------------------------------------------------------------- + void onLayerDisplayed(const sp& releaseFence) override; + void setTransformHint(uint32_t orientation) const override; + void releasePendingBuffer(nsecs_t dequeueReadyTime) override; + + bool shouldPresentNow(const DispSync& dispSync) const override; + + bool getTransformToDisplayInverse() const override; + + uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override { + return flags; + } + void pushPendingState() override; + bool applyPendingStates(Layer::State* stateToCommit) override; + + uint32_t getActiveWidth(const Layer::State& s) const override { return s.active.w; } + uint32_t getActiveHeight(const Layer::State& s) const override { return s.active.h; } + Transform getActiveTransform(const Layer::State& s) const override { + return s.active.transform; + } + Region getActiveTransparentRegion(const Layer::State& s) const override { + return s.transparentRegionHint; + } + Rect getCrop(const Layer::State& s) const; + Rect getFinalCrop(const Layer::State& /*s*/) const { return Rect::EMPTY_RECT; } + + bool setTransform(uint32_t transform) override; + bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; + bool setCrop(const Rect& crop) override; + bool setBuffer(sp buffer) override; + bool setAcquireFence(const sp& fence) override; + bool setDataspace(ui::Dataspace dataspace) override; + bool setHdrMetadata(const HdrMetadata& hdrMetadata) override; + bool setSurfaceDamageRegion(const Region& surfaceDamage) override; + bool setApi(int32_t api) override; + bool setSidebandStream(const sp& sidebandStream) override; + + bool setSize(uint32_t w, uint32_t h) override; + bool setPosition(float x, float y, bool immediate) override; + bool setTransparentRegionHint(const Region& transparent) override; + bool setMatrix(const layer_state_t::matrix22_t& matrix, + bool allowNonRectPreservingTransforms) override; + + // Override to ignore legacy layer state properties that are not used by BufferStateLayer + bool setCrop_legacy(const Rect& /*crop*/, bool /*immediate*/) override { return false; }; + bool setFinalCrop_legacy(const Rect& /*crop*/, bool /*immediate*/) override { return false; }; + void deferTransactionUntil_legacy(const sp& /*barrierHandle*/, + uint64_t /*frameNumber*/) override {} + void deferTransactionUntil_legacy(const sp& /*barrierLayer*/, + uint64_t /*frameNumber*/) override {} + // ----------------------------------------------------------------------- + + // ----------------------------------------------------------------------- + // Interface implementation for BufferLayer + // ----------------------------------------------------------------------- + bool fenceHasSignaled() const override; + +private: + nsecs_t getDesiredPresentTime() override; + std::shared_ptr getCurrentFenceTime() const override; + + void getDrawingTransformMatrix(float *matrix) override; + uint32_t getDrawingTransform() const override; + ui::Dataspace getDrawingDataSpace() const override; + Rect getDrawingCrop() const override; + uint32_t getDrawingScalingMode() const override; + Region getDrawingSurfaceDamage() const override; + const HdrMetadata& getDrawingHdrMetadata() const override; + int getDrawingApi() const override; + PixelFormat getPixelFormat() const override; + + uint64_t getFrameNumber() const override; + + bool getAutoRefresh() const override; + bool getSidebandStreamChanged() const override; + + std::optional latchSidebandStream(bool& recomputeVisibleRegions) override; + + bool hasDrawingBuffer() const override; + + void setFilteringEnabled(bool enabled) override; + + status_t bindTextureImage() const override; + status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) override; + + status_t updateActiveBuffer() override; + status_t updateFrameNumber(nsecs_t latchTime) override; + + void setHwcLayerBuffer(const sp& display) override; + // ----------------------------------------------------------------------- +private: + void onFirstRef() override; + + std::unique_ptr mTextureImage; + + std::array mTransformMatrix; + + std::atomic mSidebandStreamChanged; + + uint32_t mFrameNumber; + + // TODO(marissaw): support sticky transform for LEGACY camera mode +}; + +} // namespace android diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 10075ae35f..bac46a38b4 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -43,7 +43,7 @@ ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp& client, const } void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */, - bool useIdentityTransform) const { + bool useIdentityTransform) { half4 color = getColor(); if (color.a > 0) { computeGeometry(renderArea, getBE().mMesh, useIdentityTransform); @@ -54,7 +54,7 @@ void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */, } } -void ColorLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) const { +void ColorLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) { CompositionInfo& compositionInfo = getBE().compositionInfo; auto& engine(mFlinger->getRenderEngine()); diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index 8417135ed2..429ad79a05 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -31,8 +31,8 @@ public: virtual const char* getTypeId() const { return "ColorLayer"; } virtual void onDraw(const RenderArea& renderArea, const Region& clip, - bool useIdentityTransform) const; - void drawNow(const RenderArea& , bool ) const; + bool useIdentityTransform); + void drawNow(const RenderArea&, bool); bool isVisible() const override; void setPerFrameData(const sp& display) override; diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp index 320c0df86a..5ad5d562a8 100644 --- a/services/surfaceflinger/ContainerLayer.cpp +++ b/services/surfaceflinger/ContainerLayer.cpp @@ -28,9 +28,9 @@ ContainerLayer::ContainerLayer(SurfaceFlinger* flinger, const sp& client mDrawingState = mCurrentState; } -void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) const {} +void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) {} -void ContainerLayer::drawNow(const RenderArea&, bool) const {} +void ContainerLayer::drawNow(const RenderArea&, bool) {} bool ContainerLayer::isVisible() const { return !isHiddenByPolicy(); diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index 29a5c3a569..051e76523c 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -31,8 +31,8 @@ public: const char* getTypeId() const override { return "ContainerLayer"; } void onDraw(const RenderArea& renderArea, const Region& clip, - bool useIdentityTransform) const override; - void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const override; + bool useIdentityTransform) override; + void drawNow(const RenderArea& renderArea, bool useIdentityTransform) override; bool isVisible() const override; void setPerFrameData(const sp& display) override; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index eeee0ae863..ee9ee78fae 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -114,6 +114,17 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n mCurrentState.requested_legacy = mCurrentState.active_legacy; mCurrentState.appId = 0; mCurrentState.type = 0; + mCurrentState.active.w = 0; + mCurrentState.active.h = 0; + mCurrentState.active.transform.set(0, 0); + mCurrentState.transform = 0; + mCurrentState.transformToDisplayInverse = false; + mCurrentState.crop.makeInvalid(); + mCurrentState.acquireFence = new Fence(-1); + mCurrentState.dataspace = ui::Dataspace::UNKNOWN; + mCurrentState.hdrMetadata.validTypes = 0; + mCurrentState.surfaceDamageRegion.clear(); + mCurrentState.api = -1; // drawing state & current state are identical mDrawingState = mCurrentState; @@ -293,17 +304,19 @@ static FloatRect reduce(const FloatRect& win, const Region& exclude) { Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const { const Layer::State& s(getDrawingState()); - Rect win(s.active_legacy.w, s.active_legacy.h); + Rect win(getActiveWidth(s), getActiveHeight(s)); - if (!s.crop_legacy.isEmpty()) { - win.intersect(s.crop_legacy, &win); + Rect crop = getCrop(s); + if (!crop.isEmpty()) { + win.intersect(crop, &win); } Transform t = getTransform(); win = t.transform(win); - if (!s.finalCrop_legacy.isEmpty()) { - win.intersect(s.finalCrop_legacy, &win); + Rect finalCrop = getFinalCrop(s); + if (!finalCrop.isEmpty()) { + win.intersect(finalCrop, &win); } const sp& p = mDrawingParent.promote(); @@ -322,7 +335,7 @@ Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const { } if (reduceTransparentRegion) { - auto const screenTransparentRegion = t.transform(s.activeTransparentRegion_legacy); + auto const screenTransparentRegion = t.transform(getActiveTransparentRegion(s)); win = reduce(win, screenTransparentRegion); } @@ -331,15 +344,16 @@ Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const { FloatRect Layer::computeBounds() const { const Layer::State& s(getDrawingState()); - return computeBounds(s.activeTransparentRegion_legacy); + return computeBounds(getActiveTransparentRegion(s)); } FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const { const Layer::State& s(getDrawingState()); - Rect win(s.active_legacy.w, s.active_legacy.h); + Rect win(getActiveWidth(s), getActiveHeight(s)); - if (!s.crop_legacy.isEmpty()) { - win.intersect(s.crop_legacy, &win); + Rect crop = getCrop(s); + if (!crop.isEmpty()) { + win.intersect(crop, &win); } const auto& p = mDrawingParent.promote(); @@ -379,9 +393,10 @@ Rect Layer::computeInitialCrop(const sp& display) const { // FIXME: the 3 lines below can produce slightly incorrect clipping when we have // a viewport clipping and a window transform. we should use floating point to fix this. - Rect activeCrop(s.active_legacy.w, s.active_legacy.h); - if (!s.crop_legacy.isEmpty()) { - activeCrop.intersect(s.crop_legacy, &activeCrop); + Rect activeCrop(getActiveWidth(s), getActiveHeight(s)); + Rect crop = getCrop(s); + if (!crop.isEmpty()) { + activeCrop.intersect(crop, &activeCrop); } Transform t = getTransform(); @@ -389,8 +404,9 @@ Rect Layer::computeInitialCrop(const sp& display) const { if (!activeCrop.intersect(display->getViewport(), &activeCrop)) { activeCrop.clear(); } - if (!s.finalCrop_legacy.isEmpty()) { - if (!activeCrop.intersect(s.finalCrop_legacy, &activeCrop)) { + Rect finalCrop = getFinalCrop(s); + if (!finalCrop.isEmpty()) { + if (!activeCrop.intersect(finalCrop, &activeCrop)) { activeCrop.clear(); } } @@ -424,12 +440,12 @@ FloatRect Layer::computeCrop(const sp& display) const { // transform.inverse().transform(transform.transform(Rect)) != Rect // in which case we need to make sure the final rect is clipped to the // display bounds. - if (!activeCrop.intersect(Rect(s.active_legacy.w, s.active_legacy.h), &activeCrop)) { + if (!activeCrop.intersect(Rect(getActiveWidth(s), getActiveHeight(s)), &activeCrop)) { activeCrop.clear(); } // subtract the transparent region and snap to the bounds - activeCrop = reduce(activeCrop, s.activeTransparentRegion_legacy); + activeCrop = reduce(activeCrop, getActiveTransparentRegion(s)); // Transform the window crop to match the buffer coordinate system, // which means using the inverse of the current transform set on the @@ -449,8 +465,8 @@ FloatRect Layer::computeCrop(const sp& display) const { invTransform = (Transform(invTransformOrient) * Transform(invTransform)).getOrientation(); } - int winWidth = s.active_legacy.w; - int winHeight = s.active_legacy.h; + int winWidth = getActiveWidth(s); + int winHeight = getActiveHeight(s); if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { // If the activeCrop has been rotate the ends are rotated but not // the space itself so when transforming ends back we can't rely on @@ -462,10 +478,10 @@ FloatRect Layer::computeCrop(const sp& display) const { if (is_h_flipped == is_v_flipped) { invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H; } - winWidth = s.active_legacy.h; - winHeight = s.active_legacy.w; + winWidth = getActiveHeight(s); + winHeight = getActiveWidth(s); } - const Rect winCrop = activeCrop.transform(invTransform, s.active_legacy.w, s.active_legacy.h); + const Rect winCrop = activeCrop.transform(invTransform, getActiveWidth(s), getActiveHeight(s)); // below, crop is intersected with winCrop expressed in crop's coordinate space float xScale = crop.getWidth() / float(winWidth); @@ -518,10 +534,10 @@ void Layer::setGeometry(const sp& display, uint32_t z) { // apply the layer's transform, followed by the display's global transform // here we're guaranteed that the layer's transform preserves rects - Region activeTransparentRegion(s.activeTransparentRegion_legacy); + Region activeTransparentRegion(getActiveTransparentRegion(s)); Transform t = getTransform(); - if (!s.crop_legacy.isEmpty()) { - Rect activeCrop(s.crop_legacy); + Rect activeCrop = getCrop(s); + if (!activeCrop.isEmpty()) { activeCrop = t.transform(activeCrop); if (!activeCrop.intersect(display->getViewport(), &activeCrop)) { activeCrop.clear(); @@ -533,23 +549,24 @@ void Layer::setGeometry(const sp& display, uint32_t z) { // transform.inverse().transform(transform.transform(Rect)) != Rect // in which case we need to make sure the final rect is clipped to the // display bounds. - if (!activeCrop.intersect(Rect(s.active_legacy.w, s.active_legacy.h), &activeCrop)) { + if (!activeCrop.intersect(Rect(getActiveWidth(s), getActiveHeight(s)), &activeCrop)) { activeCrop.clear(); } // mark regions outside the crop as transparent - activeTransparentRegion.orSelf(Rect(0, 0, s.active_legacy.w, activeCrop.top)); + activeTransparentRegion.orSelf(Rect(0, 0, getActiveWidth(s), activeCrop.top)); activeTransparentRegion.orSelf( - Rect(0, activeCrop.bottom, s.active_legacy.w, s.active_legacy.h)); + Rect(0, activeCrop.bottom, getActiveWidth(s), getActiveHeight(s))); activeTransparentRegion.orSelf(Rect(0, activeCrop.top, activeCrop.left, activeCrop.bottom)); activeTransparentRegion.orSelf( - Rect(activeCrop.right, activeCrop.top, s.active_legacy.w, activeCrop.bottom)); + Rect(activeCrop.right, activeCrop.top, getActiveWidth(s), activeCrop.bottom)); } // computeBounds returns a FloatRect to provide more accuracy during the // transformation. We then round upon constructing 'frame'. Rect frame{t.transform(computeBounds(activeTransparentRegion))}; - if (!s.finalCrop_legacy.isEmpty()) { - if (!frame.intersect(s.finalCrop_legacy, &frame)) { + Rect finalCrop = getFinalCrop(s); + if (!finalCrop.isEmpty()) { + if (!frame.intersect(finalCrop, &frame)) { frame.clear(); } } @@ -682,16 +699,18 @@ void Layer::updateCursorPosition(const sp& display) { // Apply the layer's transform, followed by the display's global transform // Here we're guaranteed that the layer's transform preserves rects - Rect win(s.active_legacy.w, s.active_legacy.h); - if (!s.crop_legacy.isEmpty()) { - win.intersect(s.crop_legacy, &win); + Rect win(getActiveWidth(s), getActiveHeight(s)); + Rect crop = getCrop(s); + if (!crop.isEmpty()) { + win.intersect(crop, &win); } // Subtract the transparent region and snap to the bounds - Rect bounds = reduce(win, s.activeTransparentRegion_legacy); + Rect bounds = reduce(win, getActiveTransparentRegion(s)); Rect frame(getTransform().transform(bounds)); frame.intersect(display->getViewport(), &frame); - if (!s.finalCrop_legacy.isEmpty()) { - frame.intersect(s.finalCrop_legacy, &frame); + Rect finalCrop = getFinalCrop(s); + if (!finalCrop.isEmpty()) { + frame.intersect(finalCrop, &frame); } auto& displayTransform = display->getTransform(); auto position = displayTransform.transform(frame); @@ -709,15 +728,15 @@ void Layer::updateCursorPosition(const sp& display) { // drawing... // --------------------------------------------------------------------------- -void Layer::draw(const RenderArea& renderArea, const Region& clip) const { +void Layer::draw(const RenderArea& renderArea, const Region& clip) { onDraw(renderArea, clip, false); } -void Layer::draw(const RenderArea& renderArea, bool useIdentityTransform) const { +void Layer::draw(const RenderArea& renderArea, bool useIdentityTransform) { onDraw(renderArea, Region(renderArea.getBounds()), useIdentityTransform); } -void Layer::draw(const RenderArea& renderArea) const { +void Layer::draw(const RenderArea& renderArea) { onDraw(renderArea, Region(renderArea.getBounds()), false); } @@ -844,11 +863,12 @@ void Layer::computeGeometry(const RenderArea& renderArea, Mesh& mesh, rt = layerTransform.transform(rt); } - if (!s.finalCrop_legacy.isEmpty()) { - boundPoint(<, s.finalCrop_legacy); - boundPoint(&lb, s.finalCrop_legacy); - boundPoint(&rb, s.finalCrop_legacy); - boundPoint(&rt, s.finalCrop_legacy); + Rect finalCrop = getFinalCrop(s); + if (!finalCrop.isEmpty()) { + boundPoint(<, finalCrop); + boundPoint(&lb, finalCrop); + boundPoint(&rb, finalCrop); + boundPoint(&rt, finalCrop); } Mesh::VertexArray position(mesh.getPositionArray()); @@ -984,19 +1004,11 @@ bool Layer::applyPendingStates(State* stateToCommit) { return stateUpdateAvailable; } -uint32_t Layer::doTransaction(uint32_t flags) { - ATRACE_CALL(); - - pushPendingState(); - Layer::State c = getCurrentState(); - if (!applyPendingStates(&c)) { - return 0; - } - +uint32_t Layer::doTransactionResize(uint32_t flags, State* stateToCommit) { const Layer::State& s(getDrawingState()); - const bool sizeChanged = (c.requested_legacy.w != s.requested_legacy.w) || - (c.requested_legacy.h != s.requested_legacy.h); + const bool sizeChanged = (stateToCommit->requested_legacy.w != s.requested_legacy.w) || + (stateToCommit->requested_legacy.h != s.requested_legacy.h); if (sizeChanged) { // the size changed, we need to ask our client to request a new buffer @@ -1007,16 +1019,18 @@ uint32_t Layer::doTransaction(uint32_t flags) { " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" " requested={ wh={%4u,%4u} }}\n", this, getName().string(), mCurrentTransform, getEffectiveScalingMode(), - c.active_legacy.w, c.active_legacy.h, c.crop_legacy.left, c.crop_legacy.top, - c.crop_legacy.right, c.crop_legacy.bottom, c.crop_legacy.getWidth(), - c.crop_legacy.getHeight(), c.requested_legacy.w, c.requested_legacy.h, + stateToCommit->active_legacy.w, stateToCommit->active_legacy.h, + stateToCommit->crop_legacy.left, stateToCommit->crop_legacy.top, + stateToCommit->crop_legacy.right, stateToCommit->crop_legacy.bottom, + stateToCommit->crop_legacy.getWidth(), stateToCommit->crop_legacy.getHeight(), + stateToCommit->requested_legacy.w, stateToCommit->requested_legacy.h, s.active_legacy.w, s.active_legacy.h, s.crop_legacy.left, s.crop_legacy.top, s.crop_legacy.right, s.crop_legacy.bottom, s.crop_legacy.getWidth(), s.crop_legacy.getHeight(), s.requested_legacy.w, s.requested_legacy.h); // record the new size, form this point on, when the client request // a buffer, it'll get the new size. - setDefaultBufferSize(c.requested_legacy.w, c.requested_legacy.h); + setDefaultBufferSize(stateToCommit->requested_legacy.w, stateToCommit->requested_legacy.h); } // Don't let Layer::doTransaction update the drawing state @@ -1037,8 +1051,9 @@ uint32_t Layer::doTransaction(uint32_t flags) { // resizePending state is to avoid applying the state of the new buffer // to the old buffer. However in the state where we don't have an old buffer // there is no such concern but we may still be being used as a parent layer. - const bool resizePending = ((c.requested_legacy.w != c.active_legacy.w) || - (c.requested_legacy.h != c.active_legacy.h)) && + const bool resizePending = + ((stateToCommit->requested_legacy.w != stateToCommit->active_legacy.w) || + (stateToCommit->requested_legacy.h != stateToCommit->active_legacy.h)) && (getBE().compositionInfo.mBuffer != nullptr); if (!isFixedSize()) { if (resizePending && getBE().compositionInfo.hwc.sidebandStream == nullptr) { @@ -1062,21 +1077,37 @@ uint32_t Layer::doTransaction(uint32_t flags) { // being stored in the same data structure while having different latching rules. // b/38182305 // - // Careful that "c" and editCurrentState may not begin as equivalent due to + // Careful that "stateToCommit" and editCurrentState may not begin as equivalent due to // applyPendingStates in the presence of deferred transactions. if (mFreezeGeometryUpdates) { - float tx = c.active_legacy.transform.tx(); - float ty = c.active_legacy.transform.ty(); - c.active_legacy = c.requested_legacy; - c.active_legacy.transform.set(tx, ty); - editCurrentState.active_legacy = c.active_legacy; + float tx = stateToCommit->active_legacy.transform.tx(); + float ty = stateToCommit->active_legacy.transform.ty(); + stateToCommit->active_legacy = stateToCommit->requested_legacy; + stateToCommit->active_legacy.transform.set(tx, ty); + editCurrentState.active_legacy = stateToCommit->active_legacy; } else { editCurrentState.active_legacy = editCurrentState.requested_legacy; - c.active_legacy = c.requested_legacy; + stateToCommit->active_legacy = stateToCommit->requested_legacy; } } - if (s.active_legacy != c.active_legacy) { + return flags; +} + +uint32_t Layer::doTransaction(uint32_t flags) { + ATRACE_CALL(); + + pushPendingState(); + Layer::State c = getCurrentState(); + if (!applyPendingStates(&c)) { + return 0; + } + + flags = doTransactionResize(flags, &c); + + const Layer::State& s(getDrawingState()); + + if (getActiveGeometry(c) != getActiveGeometry(s)) { // invalidate and recompute the visible regions if needed flags |= Layer::eVisibleRegion; } @@ -1087,9 +1118,8 @@ uint32_t Layer::doTransaction(uint32_t flags) { this->contentDirty = true; // we may use linear filtering, if the matrix scales us - const uint8_t type = c.active_legacy.transform.getType(); - mNeedsFiltering = - (!c.active_legacy.transform.preserveRects() || (type >= Transform::SCALE)); + const uint8_t type = getActiveTransform(c).getType(); + mNeedsFiltering = (!getActiveTransform(c).preserveRects() || (type >= Transform::SCALE)); } // If the layer is hidden, signal and clear out all local sync points so @@ -1278,6 +1308,7 @@ bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix, setTransactionFlags(eTransactionNeeded); return true; } + bool Layer::setTransparentRegionHint(const Region& transparent) { mCurrentState.requestedTransparentRegion_legacy = transparent; mCurrentState.modified = true; @@ -1415,6 +1446,7 @@ void Layer::updateTransformHint(const sp& display) const { // debugging // ---------------------------------------------------------------------------- +// TODO(marissaw): add new layer state info to layer debugging LayerDebugInfo Layer::getLayerDebugInfo() const { LayerDebugInfo info; const Layer::State& ds = getDrawingState(); @@ -1889,14 +1921,14 @@ Transform Layer::getTransform() const { bufferHeight = p->getBE().compositionInfo.mBuffer->getWidth(); bufferWidth = p->getBE().compositionInfo.mBuffer->getHeight(); } - float sx = p->getDrawingState().active_legacy.w / static_cast(bufferWidth); - float sy = p->getDrawingState().active_legacy.h / static_cast(bufferHeight); + float sx = p->getActiveWidth(p->getDrawingState()) / static_cast(bufferWidth); + float sy = p->getActiveHeight(p->getDrawingState()) / static_cast(bufferHeight); Transform extraParentScaling; extraParentScaling.set(sx, 0, 0, sy); t = t * extraParentScaling; } } - return t * getDrawingState().active_legacy.transform; + return t * getActiveTransform(getDrawingState()); } half Layer::getAlpha() const { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 96ec84b269..a48cdffd8b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -156,6 +156,24 @@ public: SortedVector> zOrderRelatives; half4 color; + + // The fields below this point are only used by BufferStateLayer + Geometry active; + + uint32_t transform; + bool transformToDisplayInverse; + + Rect crop; + Region transparentRegionHint; + + sp buffer; + sp acquireFence; + ui::Dataspace dataspace; + HdrMetadata hdrMetadata; + Region surfaceDamageRegion; + int32_t api; + + sp sidebandStream; }; Layer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, @@ -191,11 +209,12 @@ public: // also the rendered size of the layer prior to any transformations. Parent // or local matrix transformations will not affect the size of the buffer, // but may affect it's on-screen size or clipping. - bool setSize(uint32_t w, uint32_t h); + virtual bool setSize(uint32_t w, uint32_t h); // Set a 2x2 transformation matrix on the layer. This transform // will be applied after parent transforms, but before any final // producer specified transform. - bool setMatrix(const layer_state_t::matrix22_t& matrix, bool allowNonRectPreservingTransforms); + virtual bool setMatrix(const layer_state_t::matrix22_t& matrix, + bool allowNonRectPreservingTransforms); // This second set of geometry attributes are controlled by // setGeometryAppliesWithResize, and their default mode is to be @@ -205,32 +224,45 @@ public: // setPosition operates in parent buffer space (pre parent-transform) or display // space for top-level layers. - bool setPosition(float x, float y, bool immediate); + virtual bool setPosition(float x, float y, bool immediate); // Buffer space - bool setCrop_legacy(const Rect& crop, bool immediate); + virtual bool setCrop_legacy(const Rect& crop, bool immediate); // Parent buffer space/display space - bool setFinalCrop_legacy(const Rect& crop, bool immediate); + virtual bool setFinalCrop_legacy(const Rect& crop, bool immediate); // TODO(b/38182121): Could we eliminate the various latching modes by // using the layer hierarchy? // ----------------------------------------------------------------------- - bool setLayer(int32_t z); - bool setRelativeLayer(const sp& relativeToHandle, int32_t relativeZ); - - bool setAlpha(float alpha); - bool setColor(const half3& color); - bool setTransparentRegionHint(const Region& transparent); - bool setFlags(uint8_t flags, uint8_t mask); - bool setLayerStack(uint32_t layerStack); - uint32_t getLayerStack() const; - void deferTransactionUntil_legacy(const sp& barrierHandle, uint64_t frameNumber); - void deferTransactionUntil_legacy(const sp& barrierLayer, uint64_t frameNumber); - bool setOverrideScalingMode(int32_t overrideScalingMode); - void setInfo(int32_t type, int32_t appId); - bool reparentChildren(const sp& layer); - void setChildrenDrawingParent(const sp& layer); - bool reparent(const sp& newParentHandle); - bool detachChildren(); + virtual bool setLayer(int32_t z); + virtual bool setRelativeLayer(const sp& relativeToHandle, int32_t relativeZ); + + virtual bool setAlpha(float alpha); + virtual bool setColor(const half3& color); + virtual bool setTransparentRegionHint(const Region& transparent); + virtual bool setFlags(uint8_t flags, uint8_t mask); + virtual bool setLayerStack(uint32_t layerStack); + virtual uint32_t getLayerStack() const; + virtual void deferTransactionUntil_legacy(const sp& barrierHandle, + uint64_t frameNumber); + virtual void deferTransactionUntil_legacy(const sp& barrierLayer, uint64_t frameNumber); + virtual bool setOverrideScalingMode(int32_t overrideScalingMode); + virtual void setInfo(int32_t type, int32_t appId); + virtual bool reparentChildren(const sp& layer); + virtual void setChildrenDrawingParent(const sp& layer); + virtual bool reparent(const sp& newParentHandle); + virtual bool detachChildren(); + + // Used only to set BufferStateLayer state + virtual bool setTransform(uint32_t /*transform*/) { return false; }; + virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; }; + virtual bool setCrop(const Rect& /*crop*/) { return false; }; + virtual bool setBuffer(sp /*buffer*/) { return false; }; + virtual bool setAcquireFence(const sp& /*fence*/) { return false; }; + virtual bool setDataspace(ui::Dataspace /*dataspace*/) { return false; }; + virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) { return false; }; + virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) { return false; }; + virtual bool setApi(int32_t /*api*/) { return false; }; + virtual bool setSidebandStream(const sp& /*sidebandStream*/) { return false; }; ui::Dataspace getDataSpace() const { return mCurrentDataSpace; } @@ -310,12 +342,24 @@ public: void writeToProto(LayerProto* layerInfo, int32_t displayId); + virtual Geometry getActiveGeometry(const Layer::State& s) const { return s.active_legacy; } + virtual uint32_t getActiveWidth(const Layer::State& s) const { return s.active_legacy.w; } + virtual uint32_t getActiveHeight(const Layer::State& s) const { return s.active_legacy.h; } + virtual Transform getActiveTransform(const Layer::State& s) const { + return s.active_legacy.transform; + } + virtual Region getActiveTransparentRegion(const Layer::State& s) const { + return s.activeTransparentRegion_legacy; + } + virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; } + virtual Rect getFinalCrop(const Layer::State& s) const { return s.finalCrop_legacy; } + protected: /* * onDraw - draws the surface. */ virtual void onDraw(const RenderArea& renderArea, const Region& clip, - bool useIdentityTransform) const = 0; + bool useIdentityTransform) = 0; public: virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {} @@ -369,9 +413,9 @@ public: * draw - performs some global clipping optimizations * and calls onDraw(). */ - void draw(const RenderArea& renderArea, const Region& clip) const; - void draw(const RenderArea& renderArea, bool useIdentityTransform) const; - void draw(const RenderArea& renderArea) const; + void draw(const RenderArea& renderArea, const Region& clip); + void draw(const RenderArea& renderArea, bool useIdentityTransform); + void draw(const RenderArea& renderArea); /* * drawNow uses the renderEngine to draw the layer. This is different than the @@ -381,7 +425,7 @@ public: * is used for screen captures which happens separately from the frame * compositing path. */ - virtual void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const = 0; + virtual void drawNow(const RenderArea& renderArea, bool useIdentityTransform) = 0; /* * doTransaction - process the transaction. This is a good place to figure @@ -536,7 +580,7 @@ public: // SurfaceFlinger to complete a transaction. void commitChildList(); int32_t getZ() const; - void pushPendingState(); + virtual void pushPendingState(); protected: // constant @@ -620,7 +664,8 @@ protected: bool addSyncPoint(const std::shared_ptr& point); void popPendingState(State* stateToCommit); - bool applyPendingStates(State* stateToCommit); + virtual bool applyPendingStates(State* stateToCommit); + virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit); void clearSyncPoints(); diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h index 8b371705f1..b5acebafb1 100644 --- a/services/surfaceflinger/LayerBE.h +++ b/services/surfaceflinger/LayerBE.h @@ -78,6 +78,7 @@ public: friend class Layer; friend class BufferLayer; friend class BufferQueueLayer; + friend class BufferStateLayer; friend class ColorLayer; friend class SurfaceFlinger; diff --git a/services/surfaceflinger/LayerRejecter.cpp b/services/surfaceflinger/LayerRejecter.cpp index fd0ca822c6..70558d4cc8 100644 --- a/services/surfaceflinger/LayerRejecter.cpp +++ b/services/surfaceflinger/LayerRejecter.cpp @@ -101,7 +101,8 @@ bool LayerRejecter::reject(const sp& buf, const BufferItem& item) ALOGD_IF(DEBUG_RESIZE, "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" - " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) " + " drawing={ active_legacy ={ wh={%4u,%4u} crop_legacy={%4d,%4d,%4d,%4d} " + "(%4d,%4d) " "}\n" " requested_legacy={ wh={%4u,%4u} }}\n", mName, bufWidth, bufHeight, item.mTransform, item.mScalingMode, diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 64f1eaf463..399fbd83bc 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -64,6 +64,7 @@ #include "BufferLayer.h" #include "BufferQueueLayer.h" +#include "BufferStateLayer.h" #include "Client.h" #include "ColorLayer.h" #include "Colorizer.h" @@ -2766,7 +2767,7 @@ void SurfaceFlinger::computeVisibleRegions(const sp& displa if (translucent) { if (tr.preserveRects()) { // transform the transparent region - transparentRegion = tr.transform(s.activeTransparentRegion_legacy); + transparentRegion = tr.transform(layer->getActiveTransparentRegion(s)); } else { // transformation too complex, can't do the // transparent region optimization. @@ -3551,6 +3552,37 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState // 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::eTransformChanged) { + if (layer->setTransform(s.transform)) flags |= eTraversalNeeded; + } + if (what & layer_state_t::eTransformToDisplayInverseChanged) { + if (layer->setTransformToDisplayInverse(s.transformToDisplayInverse)) + flags |= eTraversalNeeded; + } + if (what & layer_state_t::eCropChanged) { + if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; + } + if (what & layer_state_t::eBufferChanged) { + if (layer->setBuffer(s.buffer)) flags |= eTraversalNeeded; + } + if (what & layer_state_t::eAcquireFenceChanged) { + if (layer->setAcquireFence(s.acquireFence)) flags |= eTraversalNeeded; + } + if (what & layer_state_t::eDataspaceChanged) { + if (layer->setDataspace(s.dataspace)) flags |= eTraversalNeeded; + } + if (what & layer_state_t::eHdrMetadataChanged) { + if (layer->setHdrMetadata(s.hdrMetadata)) flags |= eTraversalNeeded; + } + if (what & layer_state_t::eSurfaceDamageRegionChanged) { + if (layer->setSurfaceDamageRegion(s.surfaceDamageRegion)) flags |= eTraversalNeeded; + } + if (what & layer_state_t::eApiChanged) { + if (layer->setApi(s.api)) flags |= eTraversalNeeded; + } + if (what & layer_state_t::eSidebandStreamChanged) { + if (layer->setSidebandStream(s.sidebandStream)) flags |= eTraversalNeeded; + } return flags; } @@ -3593,10 +3625,13 @@ status_t SurfaceFlinger::createLayer( String8 uniqueName = getUniqueLayerName(name); switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { - case ISurfaceComposerClient::eFXSurfaceNormal: + case ISurfaceComposerClient::eFXSurfaceBufferQueue: result = createBufferQueueLayer(client, uniqueName, w, h, flags, format, handle, gbp, &layer); + break; + case ISurfaceComposerClient::eFXSurfaceBufferState: + result = createBufferStateLayer(client, uniqueName, w, h, flags, handle, &layer); break; case ISurfaceComposerClient::eFXSurfaceColor: result = createColorLayer(client, @@ -3687,6 +3722,16 @@ status_t SurfaceFlinger::createBufferQueueLayer(const sp& client, const return err; } +status_t SurfaceFlinger::createBufferStateLayer(const sp& client, const String8& name, + uint32_t w, uint32_t h, uint32_t flags, + sp* handle, sp* outLayer) { + sp layer = new BufferStateLayer(this, client, name, w, h, flags); + *handle = layer->getHandle(); + *outLayer = layer; + + return NO_ERROR; +} + status_t SurfaceFlinger::createColorLayer(const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, sp* handle, sp* outLayer) @@ -4864,10 +4909,12 @@ status_t SurfaceFlinger::captureLayers(const sp& layerHandleBinder, const Transform& getTransform() const override { return mTransform; } Rect getBounds() const override { const Layer::State& layerState(mLayer->getDrawingState()); - return Rect(layerState.active_legacy.w, layerState.active_legacy.h); + return Rect(mLayer->getActiveWidth(layerState), mLayer->getActiveHeight(layerState)); + } + int getHeight() const override { + return mLayer->getActiveHeight(mLayer->getDrawingState()); } - int getHeight() const override { return mLayer->getDrawingState().active_legacy.h; } - int getWidth() const override { return mLayer->getDrawingState().active_legacy.w; } + int getWidth() const override { return mLayer->getActiveWidth(mLayer->getDrawingState()); } bool isSecure() const override { return false; } bool needsFiltering() const override { return false; } Rect getSourceCrop() const override { @@ -4935,12 +4982,12 @@ status_t SurfaceFlinger::captureLayers(const sp& layerHandleBinder, Rect crop(sourceCrop); if (sourceCrop.width() <= 0) { crop.left = 0; - crop.right = parent->getCurrentState().active_legacy.w; + crop.right = parent->getActiveWidth(parent->getCurrentState()); } if (sourceCrop.height() <= 0) { crop.top = 0; - crop.bottom = parent->getCurrentState().active_legacy.h; + crop.bottom = parent->getActiveHeight(parent->getCurrentState()); } int32_t reqWidth = crop.width() * frameScale; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a750636520..eaaf7420f1 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -356,6 +356,7 @@ private: friend class Layer; friend class BufferLayer; friend class BufferQueueLayer; + friend class BufferStateLayer; friend class MonitoredProducer; // For unit tests @@ -535,6 +536,10 @@ private: sp* outHandle, sp* outGbp, sp* outLayer); + status_t createBufferStateLayer(const sp& client, const String8& name, uint32_t w, + uint32_t h, uint32_t flags, sp* outHandle, + sp* outLayer); + status_t createColorLayer(const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, sp* outHandle, sp* outLayer); diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index c42213a28d..f504c13a97 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -30,6 +30,7 @@ namespace android { // ---------------------------------------------------------------------------- +// TODO(marissaw): add new layer state values to SurfaceInterceptor SurfaceInterceptor::~SurfaceInterceptor() = default; diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 2ce32b5967..bde6614b61 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -62,38 +62,54 @@ const Color Color::WHITE{255, 255, 255, 255}; const Color Color::BLACK{0, 0, 0, 255}; const Color Color::TRANSPARENT{0, 0, 0, 0}; +using android::hardware::graphics::common::V1_1::BufferUsage; + std::ostream& operator<<(std::ostream& os, const Color& color) { os << int(color.r) << ", " << int(color.g) << ", " << int(color.b) << ", " << int(color.a); return os; } // Fill a region with the specified color. -void fillBufferColor(const ANativeWindow_Buffer& buffer, const Rect& rect, const Color& color) { - int32_t x = rect.left; - int32_t y = rect.top; - int32_t width = rect.right - rect.left; - int32_t height = rect.bottom - rect.top; - - if (x < 0) { - width += x; - x = 0; +void fillANativeWindowBufferColor(const ANativeWindow_Buffer& buffer, const Rect& rect, + const Color& color) { + Rect r(0, 0, buffer.width, buffer.height); + if (!r.intersect(rect, &r)) { + return; } - if (y < 0) { - height += y; - y = 0; - } - if (x + width > buffer.width) { - x = std::min(x, buffer.width); - width = buffer.width - x; + + int32_t width = r.right - r.left; + int32_t height = r.bottom - r.top; + + for (int32_t row = 0; row < height; row++) { + uint8_t* dst = + static_cast(buffer.bits) + (buffer.stride * (r.top + row) + r.left) * 4; + for (int32_t column = 0; column < width; column++) { + dst[0] = color.r; + dst[1] = color.g; + dst[2] = color.b; + dst[3] = color.a; + dst += 4; + } } - if (y + height > buffer.height) { - y = std::min(y, buffer.height); - height = buffer.height - y; +} + +// Fill a region with the specified color. +void fillGraphicBufferColor(const sp& buffer, const Rect& rect, const Color& color) { + Rect r(0, 0, buffer->width, buffer->height); + if (!r.intersect(rect, &r)) { + return; } - for (int32_t j = 0; j < height; j++) { - uint8_t* dst = static_cast(buffer.bits) + (buffer.stride * (y + j) + x) * 4; - for (int32_t i = 0; i < width; i++) { + int32_t width = r.right - r.left; + int32_t height = r.bottom - r.top; + + uint8_t* pixels; + buffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast(&pixels)); + + for (int32_t row = 0; row < height; row++) { + uint8_t* dst = pixels + (buffer->getStride() * (r.top + row) + r.left) * 4; + for (int32_t column = 0; column < width; column++) { dst[0] = color.r; dst[1] = color.g; dst[2] = color.b; @@ -101,6 +117,7 @@ void fillBufferColor(const ANativeWindow_Buffer& buffer, const Rect& rect, const dst += 4; } } + buffer->unlock(); } // Check if a region has the specified color. @@ -301,8 +318,8 @@ protected: ASSERT_NO_FATAL_FAILURE(SetUpDisplay()); } - sp createLayer(const char* name, uint32_t width, uint32_t height, - uint32_t flags = 0) { + virtual sp createLayer(const char* name, uint32_t width, uint32_t height, + uint32_t flags = 0) { auto layer = mClient->createSurface(String8(name), width, height, PIXEL_FORMAT_RGBA_8888, flags); EXPECT_NE(nullptr, layer.get()) << "failed to create SurfaceControl"; @@ -319,7 +336,7 @@ protected: return layer; } - ANativeWindow_Buffer getLayerBuffer(const sp& layer) { + ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp& layer) { // wait for previous transactions (such as setSize) to complete Transaction().apply(true); @@ -329,35 +346,103 @@ protected: return buffer; } - void postLayerBuffer(const sp& layer) { + void postBufferQueueLayerBuffer(const sp& layer) { ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost()); // wait for the newly posted buffer to be latched waitForLayerBuffers(); } - void fillLayerColor(const sp& layer, const Color& color) { + virtual void fillBufferQueueLayerColor(const sp& layer, const Color& color, + int32_t bufferWidth, int32_t bufferHeight) { ANativeWindow_Buffer buffer; - ASSERT_NO_FATAL_FAILURE(buffer = getLayerBuffer(layer)); - fillBufferColor(buffer, Rect(0, 0, buffer.width, buffer.height), color); - postLayerBuffer(layer); + ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer)); + fillANativeWindowBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight), color); + postBufferQueueLayerBuffer(layer); + } + + virtual void fillBufferStateLayerColor(const sp& layer, const Color& color, + int32_t bufferWidth, int32_t bufferHeight) { + sp buffer = + new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + fillGraphicBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight), color); + Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply(); + } + + void fillLayerColor(uint32_t mLayerType, const sp& layer, const Color& color, + int32_t bufferWidth, int32_t bufferHeight) { + switch (mLayerType) { + case ISurfaceComposerClient::eFXSurfaceBufferQueue: + fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight); + break; + case ISurfaceComposerClient::eFXSurfaceBufferState: + fillBufferStateLayerColor(layer, color, bufferWidth, bufferHeight); + break; + default: + ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType; + } } - void fillLayerQuadrant(const sp& layer, const Color& topLeft, + void fillLayerQuadrant(uint32_t mLayerType, const sp& layer, + int32_t bufferWidth, int32_t bufferHeight, const Color& topLeft, const Color& topRight, const Color& bottomLeft, const Color& bottomRight) { + switch (mLayerType) { + case ISurfaceComposerClient::eFXSurfaceBufferQueue: + fillBufferQueueLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight, + bottomLeft, bottomRight); + break; + case ISurfaceComposerClient::eFXSurfaceBufferState: + fillBufferStateLayerQuadrant(layer, bufferWidth, bufferHeight, topLeft, topRight, + bottomLeft, bottomRight); + break; + default: + ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType; + } + } + + virtual void fillBufferQueueLayerQuadrant(const sp& layer, int32_t bufferWidth, + int32_t bufferHeight, const Color& topLeft, + const Color& topRight, const Color& bottomLeft, + const Color& bottomRight) { ANativeWindow_Buffer buffer; - ASSERT_NO_FATAL_FAILURE(buffer = getLayerBuffer(layer)); - ASSERT_TRUE(buffer.width % 2 == 0 && buffer.height % 2 == 0); + ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer)); + ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0); + + const int32_t halfW = bufferWidth / 2; + const int32_t halfH = bufferHeight / 2; + fillANativeWindowBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft); + fillANativeWindowBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH), topRight); + fillANativeWindowBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight), bottomLeft); + fillANativeWindowBufferColor(buffer, Rect(halfW, halfH, bufferWidth, bufferHeight), + bottomRight); + + postBufferQueueLayerBuffer(layer); + } - const int32_t halfW = buffer.width / 2; - const int32_t halfH = buffer.height / 2; - fillBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft); - fillBufferColor(buffer, Rect(halfW, 0, buffer.width, halfH), topRight); - fillBufferColor(buffer, Rect(0, halfH, halfW, buffer.height), bottomLeft); - fillBufferColor(buffer, Rect(halfW, halfH, buffer.width, buffer.height), bottomRight); + virtual void fillBufferStateLayerQuadrant(const sp& layer, int32_t bufferWidth, + int32_t bufferHeight, const Color& topLeft, + const Color& topRight, const Color& bottomLeft, + const Color& bottomRight) { + sp buffer = + new GraphicBuffer(bufferWidth, bufferHeight, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); - postLayerBuffer(layer); + ASSERT_TRUE(bufferWidth % 2 == 0 && bufferHeight % 2 == 0); + + const int32_t halfW = bufferWidth / 2; + const int32_t halfH = bufferHeight / 2; + fillGraphicBufferColor(buffer, Rect(0, 0, halfW, halfH), topLeft); + fillGraphicBufferColor(buffer, Rect(halfW, 0, bufferWidth, halfH), topRight); + fillGraphicBufferColor(buffer, Rect(0, halfH, halfW, bufferHeight), bottomLeft); + fillGraphicBufferColor(buffer, Rect(halfW, halfH, bufferWidth, bufferHeight), bottomRight); + + Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply(); } sp screenshot() { @@ -376,6 +461,10 @@ protected: // leave room for ~256 layers const int32_t mLayerZBase = std::numeric_limits::max() - 256; + void setPositionWithResizeHelper(uint32_t layerType); + void setSizeBasicHelper(uint32_t layerType); + void setMatrixWithResizeHelper(uint32_t layerType); + private: void SetUpDisplay() { mDisplay = mClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); @@ -404,10 +493,48 @@ private: int32_t mBufferPostDelay; }; -TEST_F(LayerTransactionTest, SetPositionBasic) { +class LayerTypeTransactionTest : public LayerTransactionTest, + public ::testing::WithParamInterface { +public: + LayerTypeTransactionTest() { mLayerType = GetParam(); } + + sp createLayer(const char* name, uint32_t width, uint32_t height, + uint32_t flags = 0) override { + // if the flags already have a layer type specified, return an error + if (flags & ISurfaceComposerClient::eFXSurfaceMask) { + return nullptr; + } + return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType); + } + + void fillLayerColor(const sp& layer, const Color& color, int32_t bufferWidth, + int32_t bufferHeight) { + ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerColor(mLayerType, layer, color, + bufferWidth, bufferHeight)); + } + + void fillLayerQuadrant(const sp& layer, int32_t bufferWidth, + int32_t bufferHeight, const Color& topLeft, const Color& topRight, + const Color& bottomLeft, const Color& bottomRight) { + ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerQuadrant(mLayerType, layer, + bufferWidth, bufferHeight, + topLeft, topRight, + bottomLeft, bottomRight)); + } + +protected: + uint32_t mLayerType; +}; + +INSTANTIATE_TEST_CASE_P( + LayerTypeTransactionTests, LayerTypeTransactionTest, + ::testing::Values(static_cast(ISurfaceComposerClient::eFXSurfaceBufferQueue), + static_cast(ISurfaceComposerClient::eFXSurfaceBufferState))); + +TEST_P(LayerTypeTransactionTest, SetPositionBasic) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); { SCOPED_TRACE("default position"); @@ -425,10 +552,10 @@ TEST_F(LayerTransactionTest, SetPositionBasic) { } } -TEST_F(LayerTransactionTest, SetPositionRounding) { +TEST_P(LayerTypeTransactionTest, SetPositionRounding) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); // GLES requires only 4 bits of subpixel precision during rasterization // XXX GLES composition does not match HWC composition due to precision @@ -447,10 +574,10 @@ TEST_F(LayerTransactionTest, SetPositionRounding) { } } -TEST_F(LayerTransactionTest, SetPositionOutOfBounds) { +TEST_P(LayerTypeTransactionTest, SetPositionOutOfBounds) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); Transaction().setPosition(layer, -32, -32).apply(); { @@ -465,10 +592,10 @@ TEST_F(LayerTransactionTest, SetPositionOutOfBounds) { } } -TEST_F(LayerTransactionTest, SetPositionPartiallyOutOfBounds) { +TEST_P(LayerTypeTransactionTest, SetPositionPartiallyOutOfBounds) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); // partially out of bounds Transaction().setPosition(layer, -30, -30).apply(); @@ -486,10 +613,10 @@ TEST_F(LayerTransactionTest, SetPositionPartiallyOutOfBounds) { } } -TEST_F(LayerTransactionTest, SetPositionWithResize) { +void LayerTransactionTest::setPositionWithResizeHelper(uint32_t layerType) { sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32, layerType)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 32, 32)); // setPosition is applied immediately by default, with or without resize // pending @@ -497,21 +624,43 @@ TEST_F(LayerTransactionTest, SetPositionWithResize) { { SCOPED_TRACE("resize pending"); auto shot = screenshot(); - shot->expectColor(Rect(5, 10, 37, 42), Color::RED); - shot->expectBorder(Rect(5, 10, 37, 42), Color::BLACK); + Rect rect; + switch (layerType) { + case ISurfaceComposerClient::eFXSurfaceBufferQueue: + rect = {5, 10, 37, 42}; + break; + case ISurfaceComposerClient::eFXSurfaceBufferState: + rect = {5, 10, 69, 74}; + break; + default: + ASSERT_FALSE(true) << "Unsupported layer type"; + } + + shot->expectColor(rect, Color::RED); + shot->expectBorder(rect, Color::BLACK); } - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 64, 64)); { SCOPED_TRACE("resize applied"); screenshot()->expectColor(Rect(5, 10, 69, 74), Color::RED); } } -TEST_F(LayerTransactionTest, SetPositionWithNextResize) { +TEST_F(LayerTransactionTest, SetPositionWithResize_BufferQueue) { + ASSERT_NO_FATAL_FAILURE( + setPositionWithResizeHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue)); +} + +TEST_F(LayerTransactionTest, SetPositionWithResize_BufferState) { + ASSERT_NO_FATAL_FAILURE( + setPositionWithResizeHelper(ISurfaceComposerClient::eFXSurfaceBufferState)); +} + +TEST_F(LayerTransactionTest, SetPositionWithNextResize_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // request setPosition to be applied with the next resize Transaction().setPosition(layer, 5, 10).setGeometryAppliesWithResize(layer).apply(); @@ -533,17 +682,17 @@ TEST_F(LayerTransactionTest, SetPositionWithNextResize) { } // finally resize and latch the buffer - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 64, 64)); { SCOPED_TRACE("new position applied"); screenshot()->expectColor(Rect(15, 20, 79, 84), Color::RED); } } -TEST_F(LayerTransactionTest, SetPositionWithNextResizeScaleToWindow) { +TEST_F(LayerTransactionTest, SetPositionWithNextResizeScaleToWindow_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // setPosition is not immediate even with SCALE_TO_WINDOW override Transaction() @@ -557,27 +706,38 @@ TEST_F(LayerTransactionTest, SetPositionWithNextResizeScaleToWindow) { screenshot()->expectColor(Rect(0, 0, 64, 64), Color::RED); } - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 64, 64)); { SCOPED_TRACE("new position applied"); screenshot()->expectColor(Rect(5, 10, 69, 74), Color::RED); } } -TEST_F(LayerTransactionTest, SetSizeBasic) { +void LayerTransactionTest::setSizeBasicHelper(uint32_t layerType) { sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32, layerType)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 32, 32)); Transaction().setSize(layer, 64, 64).apply(); { SCOPED_TRACE("resize pending"); auto shot = screenshot(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + Rect rect; + switch (layerType) { + case ISurfaceComposerClient::eFXSurfaceBufferQueue: + rect = {0, 0, 32, 32}; + break; + case ISurfaceComposerClient::eFXSurfaceBufferState: + rect = {0, 0, 64, 64}; + break; + default: + ASSERT_FALSE(true) << "Unsupported layer type"; + } + shot->expectColor(rect, Color::RED); + shot->expectBorder(rect, Color::BLACK); } - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 64, 64)); { SCOPED_TRACE("resize applied"); auto shot = screenshot(); @@ -586,14 +746,22 @@ TEST_F(LayerTransactionTest, SetSizeBasic) { } } -TEST_F(LayerTransactionTest, SetSizeInvalid) { +TEST_F(LayerTransactionTest, SetSizeBasic_BufferQueue) { + setSizeBasicHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue); +} + +TEST_F(LayerTransactionTest, SetSizeBasic_BufferState) { + setSizeBasicHelper(ISurfaceComposerClient::eFXSurfaceBufferState); +} + +TEST_P(LayerTypeTransactionTest, SetSizeInvalid) { // cannot test robustness against invalid sizes (zero or really huge) } -TEST_F(LayerTransactionTest, SetSizeWithScaleToWindow) { +TEST_P(LayerTypeTransactionTest, SetSizeWithScaleToWindow) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); // setSize is immediate with SCALE_TO_WINDOW, unlike setPosition Transaction() @@ -603,13 +771,13 @@ TEST_F(LayerTransactionTest, SetSizeWithScaleToWindow) { screenshot()->expectColor(Rect(0, 0, 64, 64), Color::RED); } -TEST_F(LayerTransactionTest, SetZBasic) { +TEST_P(LayerTypeTransactionTest, SetZBasic) { sp layerR; sp layerG; ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32)); Transaction().setLayer(layerR, mLayerZBase + 1).apply(); { @@ -624,13 +792,13 @@ TEST_F(LayerTransactionTest, SetZBasic) { } } -TEST_F(LayerTransactionTest, SetZNegative) { +TEST_P(LayerTypeTransactionTest, SetZNegative) { sp layerR; sp layerG; ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32)); Transaction().setLayer(layerR, -1).setLayer(layerG, -2).apply(); { @@ -649,13 +817,13 @@ TEST_F(LayerTransactionTest, SetZNegative) { } } -TEST_F(LayerTransactionTest, SetRelativeZBasic) { +TEST_P(LayerTypeTransactionTest, SetRelativeZBasic) { sp layerR; sp layerG; ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32)); Transaction() .setPosition(layerG, 16, 16) @@ -677,16 +845,16 @@ TEST_F(LayerTransactionTest, SetRelativeZBasic) { } } -TEST_F(LayerTransactionTest, SetRelativeZNegative) { +TEST_P(LayerTypeTransactionTest, SetRelativeZNegative) { sp layerR; sp layerG; sp layerB; ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerB = createLayer("test B", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE, 32, 32)); // layerR = mLayerZBase, layerG = layerR - 1, layerB = -2 Transaction().setRelativeLayer(layerG, layerR->getHandle(), -1).setLayer(layerB, -2).apply(); @@ -697,16 +865,16 @@ TEST_F(LayerTransactionTest, SetRelativeZNegative) { screenshot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); } -TEST_F(LayerTransactionTest, SetRelativeZGroup) { +TEST_P(LayerTypeTransactionTest, SetRelativeZGroup) { sp layerR; sp layerG; sp layerB; ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerB = createLayer("test B", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE, 32, 32)); // layerR = 0, layerG = layerR + 3, layerB = 2 Transaction() @@ -764,14 +932,14 @@ TEST_F(LayerTransactionTest, SetRelativeZGroup) { } } -TEST_F(LayerTransactionTest, SetRelativeZBug64572777) { +TEST_P(LayerTypeTransactionTest, SetRelativeZBug64572777) { sp layerR; sp layerG; ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32)); Transaction() .setPosition(layerG, 16, 16) @@ -783,10 +951,10 @@ TEST_F(LayerTransactionTest, SetRelativeZBug64572777) { screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); } -TEST_F(LayerTransactionTest, SetFlagsHidden) { +TEST_P(LayerTypeTransactionTest, SetFlagsHidden) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); Transaction().setFlags(layer, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden).apply(); { @@ -801,14 +969,14 @@ TEST_F(LayerTransactionTest, SetFlagsHidden) { } } -TEST_F(LayerTransactionTest, SetFlagsOpaque) { +TEST_P(LayerTypeTransactionTest, SetFlagsOpaque) { const Color translucentRed = {100, 0, 0, 100}; sp layerR; sp layerG; ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, translucentRed)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, translucentRed, 32, 32)); ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32)); Transaction() .setLayer(layerR, mLayerZBase + 1) @@ -827,10 +995,10 @@ TEST_F(LayerTransactionTest, SetFlagsOpaque) { } } -TEST_F(LayerTransactionTest, SetFlagsSecure) { +TEST_P(LayerTypeTransactionTest, SetFlagsSecure) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); sp composer = ComposerService::getComposerService(); sp outBuffer; @@ -847,19 +1015,19 @@ TEST_F(LayerTransactionTest, SetFlagsSecure) { false)); } -TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic) { +TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic_BufferQueue) { const Rect top(0, 0, 32, 16); const Rect bottom(0, 16, 32, 32); sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); ANativeWindow_Buffer buffer; - ASSERT_NO_FATAL_FAILURE(buffer = getLayerBuffer(layer)); - ASSERT_NO_FATAL_FAILURE(fillBufferColor(buffer, top, Color::TRANSPARENT)); - ASSERT_NO_FATAL_FAILURE(fillBufferColor(buffer, bottom, Color::RED)); + ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer)); + ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, top, Color::TRANSPARENT)); + ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, bottom, Color::RED)); // setTransparentRegionHint always applies to the following buffer Transaction().setTransparentRegionHint(layer, Region(top)).apply(); - ASSERT_NO_FATAL_FAILURE(postLayerBuffer(layer)); + ASSERT_NO_FATAL_FAILURE(postBufferQueueLayerBuffer(layer)); { SCOPED_TRACE("top transparent"); auto shot = screenshot(); @@ -875,10 +1043,10 @@ TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic) { shot->expectColor(bottom, Color::RED); } - ASSERT_NO_FATAL_FAILURE(buffer = getLayerBuffer(layer)); - ASSERT_NO_FATAL_FAILURE(fillBufferColor(buffer, top, Color::RED)); - ASSERT_NO_FATAL_FAILURE(fillBufferColor(buffer, bottom, Color::TRANSPARENT)); - ASSERT_NO_FATAL_FAILURE(postLayerBuffer(layer)); + ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer)); + ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, top, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillANativeWindowBufferColor(buffer, bottom, Color::TRANSPARENT)); + ASSERT_NO_FATAL_FAILURE(postBufferQueueLayerBuffer(layer)); { SCOPED_TRACE("bottom transparent"); auto shot = screenshot(); @@ -887,7 +1055,58 @@ TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic) { } } -TEST_F(LayerTransactionTest, SetTransparentRegionHintOutOfBounds) { +TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic_BufferState) { + const Rect top(0, 0, 32, 16); + const Rect bottom(0, 16, 32, 32); + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + sp buffer = + new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + + ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, top, Color::TRANSPARENT)); + ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, bottom, Color::RED)); + Transaction() + .setTransparentRegionHint(layer, Region(top)) + .setBuffer(layer, buffer) + .setSize(layer, 32, 32) + .apply(); + { + SCOPED_TRACE("top transparent"); + auto shot = screenshot(); + shot->expectColor(top, Color::BLACK); + shot->expectColor(bottom, Color::RED); + } + + Transaction().setTransparentRegionHint(layer, Region(bottom)).apply(); + { + SCOPED_TRACE("transparent region hint intermediate"); + auto shot = screenshot(); + shot->expectColor(top, Color::BLACK); + shot->expectColor(bottom, Color::BLACK); + } + + buffer = new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + + ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, top, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillGraphicBufferColor(buffer, bottom, Color::TRANSPARENT)); + Transaction().setBuffer(layer, buffer).setSize(layer, 32, 32).apply(); + { + SCOPED_TRACE("bottom transparent"); + auto shot = screenshot(); + shot->expectColor(top, Color::RED); + shot->expectColor(bottom, Color::BLACK); + } +} + +TEST_P(LayerTypeTransactionTest, SetTransparentRegionHintOutOfBounds) { sp layerTransparent; sp layerR; ASSERT_NO_FATAL_FAILURE(layerTransparent = createLayer("test transparent", 32, 32)); @@ -900,18 +1119,18 @@ TEST_F(LayerTransactionTest, SetTransparentRegionHintOutOfBounds) { .setPosition(layerR, 16, 16) .setLayer(layerR, mLayerZBase + 1) .apply(); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerTransparent, Color::TRANSPARENT)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerTransparent, Color::TRANSPARENT, 32, 32)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerR, Color::RED, 32, 32)); screenshot()->expectColor(Rect(16, 16, 48, 48), Color::RED); } -TEST_F(LayerTransactionTest, SetAlphaBasic) { +TEST_P(LayerTypeTransactionTest, SetAlphaBasic) { sp layer1; sp layer2; ASSERT_NO_FATAL_FAILURE(layer1 = createLayer("test 1", 32, 32)); ASSERT_NO_FATAL_FAILURE(layer2 = createLayer("test 2", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer1, {64, 0, 0, 255})); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer2, {0, 64, 0, 255})); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer1, {64, 0, 0, 255}, 32, 32)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer2, {0, 64, 0, 255}, 32, 32)); Transaction() .setAlpha(layer1, 0.25f) @@ -931,11 +1150,11 @@ TEST_F(LayerTransactionTest, SetAlphaBasic) { } } -TEST_F(LayerTransactionTest, SetAlphaClamped) { +TEST_P(LayerTypeTransactionTest, SetAlphaClamped) { const Color color = {64, 0, 0, 255}; sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, color)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, color, 32, 32)); Transaction().setAlpha(layer, 2.0f).apply(); { @@ -954,7 +1173,7 @@ TEST_F(LayerTransactionTest, SetColorBasic) { sp bufferLayer; sp colorLayer; ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test bg", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(bufferLayer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE( colorLayer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceColor)); @@ -989,7 +1208,7 @@ TEST_F(LayerTransactionTest, SetColorWithAlpha) { sp bufferLayer; sp colorLayer; ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test bg", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(bufferLayer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE( colorLayer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceColor)); @@ -1014,7 +1233,7 @@ TEST_F(LayerTransactionTest, SetColorWithParentAlpha_Bug74220420) { sp colorLayer; ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test bg", 32, 32)); ASSERT_NO_FATAL_FAILURE(parentLayer = createLayer("parentWithAlpha", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(bufferLayer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer( "childWithColor", 32, 32, ISurfaceComposerClient::eFXSurfaceColor)); @@ -1034,20 +1253,20 @@ TEST_F(LayerTransactionTest, SetColorWithParentAlpha_Bug74220420) { tolerance); } -TEST_F(LayerTransactionTest, SetColorWithBuffer) { +TEST_P(LayerTypeTransactionTest, SetColorWithBuffer) { sp bufferLayer; ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(bufferLayer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(bufferLayer, Color::RED, 32, 32)); // color is ignored Transaction().setColor(bufferLayer, half3(0.0f, 1.0f, 0.0f)).apply(); screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); } -TEST_F(LayerTransactionTest, SetLayerStackBasic) { +TEST_P(LayerTypeTransactionTest, SetLayerStackBasic) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); Transaction().setLayerStack(layer, mDisplayLayerStack + 1).apply(); { @@ -1062,11 +1281,11 @@ TEST_F(LayerTransactionTest, SetLayerStackBasic) { } } -TEST_F(LayerTransactionTest, SetMatrixBasic) { +TEST_P(LayerTypeTransactionTest, SetMatrixBasic) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); ASSERT_NO_FATAL_FAILURE( - fillLayerQuadrant(layer, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); + fillLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); Transaction().setMatrix(layer, 1.0f, 0.0f, 0.0f, 1.0f).setPosition(layer, 0, 0).apply(); { @@ -1104,11 +1323,11 @@ TEST_F(LayerTransactionTest, SetMatrixBasic) { } } -TEST_F(LayerTransactionTest, SetMatrixRot45) { +TEST_P(LayerTypeTransactionTest, SetMatrixRot45) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); ASSERT_NO_FATAL_FAILURE( - fillLayerQuadrant(layer, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); + fillLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); const float rot = M_SQRT1_2; // 45 degrees const float trans = M_SQRT2 * 16.0f; @@ -1127,31 +1346,52 @@ TEST_F(LayerTransactionTest, SetMatrixRot45) { shot->expectColor(get8x8Rect(2 * unit, 3 * unit), Color::WHITE); } -TEST_F(LayerTransactionTest, SetMatrixWithResize) { +void LayerTransactionTest::setMatrixWithResizeHelper(uint32_t layerType) { sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32, layerType)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 32, 32)); // setMatrix is applied after any pending resize, unlike setPosition Transaction().setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f).setSize(layer, 64, 64).apply(); { SCOPED_TRACE("resize pending"); auto shot = screenshot(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + Rect rect; + switch (layerType) { + case ISurfaceComposerClient::eFXSurfaceBufferQueue: + rect = {0, 0, 32, 32}; + break; + case ISurfaceComposerClient::eFXSurfaceBufferState: + rect = {0, 0, 128, 128}; + break; + default: + ASSERT_FALSE(true) << "Unsupported layer type"; + } + shot->expectColor(rect, Color::RED); + shot->expectBorder(rect, Color::BLACK); } - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerType, layer, Color::RED, 64, 64)); { SCOPED_TRACE("resize applied"); screenshot()->expectColor(Rect(0, 0, 128, 128), Color::RED); } } -TEST_F(LayerTransactionTest, SetMatrixWithScaleToWindow) { +TEST_F(LayerTransactionTest, SetMatrixWithResize_BufferQueue) { + ASSERT_NO_FATAL_FAILURE( + setMatrixWithResizeHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue)); +} + +TEST_F(LayerTransactionTest, SetMatrixWithResize_BufferState) { + ASSERT_NO_FATAL_FAILURE( + setMatrixWithResizeHelper(ISurfaceComposerClient::eFXSurfaceBufferState)); +} + +TEST_P(LayerTypeTransactionTest, SetMatrixWithScaleToWindow) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, 32, 32)); // setMatrix is immediate with SCALE_TO_WINDOW, unlike setPosition Transaction() @@ -1162,11 +1402,11 @@ TEST_F(LayerTransactionTest, SetMatrixWithScaleToWindow) { screenshot()->expectColor(Rect(0, 0, 128, 128), Color::RED); } -TEST_F(LayerTransactionTest, SetOverrideScalingModeBasic) { +TEST_P(LayerTypeTransactionTest, SetOverrideScalingModeBasic) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); ASSERT_NO_FATAL_FAILURE( - fillLayerQuadrant(layer, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); + fillLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); // XXX SCALE_CROP is not respected; calling setSize and // setOverrideScalingMode in separate transactions does not work @@ -1182,10 +1422,10 @@ TEST_F(LayerTransactionTest, SetOverrideScalingModeBasic) { } } -TEST_F(LayerTransactionTest, SetCropBasic) { +TEST_F(LayerTransactionTest, SetCropBasic_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); const Rect crop(8, 8, 24, 24); Transaction().setCrop_legacy(layer, crop).apply(); @@ -1194,10 +1434,23 @@ TEST_F(LayerTransactionTest, SetCropBasic) { shot->expectBorder(crop, Color::BLACK); } -TEST_F(LayerTransactionTest, SetCropEmpty) { +TEST_F(LayerTransactionTest, SetCropBasic_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + const Rect crop(8, 8, 24, 24); + + Transaction().setCrop(layer, crop).apply(); + auto shot = screenshot(); + shot->expectColor(crop, Color::RED); + shot->expectBorder(crop, Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetCropEmpty_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); { SCOPED_TRACE("empty rect"); @@ -1212,10 +1465,29 @@ TEST_F(LayerTransactionTest, SetCropEmpty) { } } -TEST_F(LayerTransactionTest, SetCropOutOfBounds) { +TEST_F(LayerTransactionTest, SetCropEmpty_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + { + SCOPED_TRACE("empty rect"); + Transaction().setCrop(layer, Rect(8, 8, 8, 8)).apply(); + screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); + } + + { + SCOPED_TRACE("negative rect"); + Transaction().setCrop(layer, Rect(8, 8, 0, 0)).apply(); + screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); + } +} + +TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); Transaction().setCrop_legacy(layer, Rect(-128, -64, 128, 64)).apply(); auto shot = screenshot(); @@ -1223,10 +1495,22 @@ TEST_F(LayerTransactionTest, SetCropOutOfBounds) { shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } -TEST_F(LayerTransactionTest, SetCropWithTranslation) { +TEST_F(LayerTransactionTest, SetCropOutOfBounds_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + Transaction().setCrop(layer, Rect(-128, -64, 128, 64)).apply(); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetCropWithTranslation_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); const Point position(32, 32); const Rect crop(8, 8, 24, 24); @@ -1236,10 +1520,24 @@ TEST_F(LayerTransactionTest, SetCropWithTranslation) { shot->expectBorder(crop + position, Color::BLACK); } -TEST_F(LayerTransactionTest, SetCropWithScale) { +TEST_F(LayerTransactionTest, SetCropWithTranslation_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + const Point position(32, 32); + const Rect crop(8, 8, 24, 24); + Transaction().setPosition(layer, position.x, position.y).setCrop(layer, crop).apply(); + auto shot = screenshot(); + shot->expectColor(crop + position, Color::RED); + shot->expectBorder(crop + position, Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetCropWithScale_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // crop is affected by matrix Transaction() @@ -1251,10 +1549,26 @@ TEST_F(LayerTransactionTest, SetCropWithScale) { shot->expectBorder(Rect(16, 16, 48, 48), Color::BLACK); } -TEST_F(LayerTransactionTest, SetCropWithResize) { +TEST_F(LayerTransactionTest, SetCropWithScale_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + // crop is affected by matrix + Transaction() + .setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f) + .setCrop(layer, Rect(8, 8, 24, 24)) + .apply(); + auto shot = screenshot(); + shot->expectColor(Rect(16, 16, 48, 48), Color::RED); + shot->expectBorder(Rect(16, 16, 48, 48), Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetCropWithResize_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // setCrop_legacy is applied immediately by default, with or without resize pending Transaction().setCrop_legacy(layer, Rect(8, 8, 24, 24)).setSize(layer, 16, 16).apply(); @@ -1265,7 +1579,7 @@ TEST_F(LayerTransactionTest, SetCropWithResize) { shot->expectBorder(Rect(8, 8, 24, 24), Color::BLACK); } - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); { SCOPED_TRACE("resize applied"); auto shot = screenshot(); @@ -1274,10 +1588,34 @@ TEST_F(LayerTransactionTest, SetCropWithResize) { } } -TEST_F(LayerTransactionTest, SetCropWithNextResize) { +TEST_F(LayerTransactionTest, SetCropWithResize_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + // setCrop_legacy is applied immediately by default, with or without resize pending + Transaction().setCrop(layer, Rect(8, 8, 24, 24)).setSize(layer, 16, 16).apply(); + { + SCOPED_TRACE("new buffer pending"); + auto shot = screenshot(); + shot->expectColor(Rect(8, 8, 16, 16), Color::RED); + shot->expectBorder(Rect(8, 8, 16, 16), Color::BLACK); + } + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 16, 16)); + { + SCOPED_TRACE("new buffer"); + auto shot = screenshot(); + shot->expectColor(Rect(8, 8, 16, 16), Color::RED); + shot->expectBorder(Rect(8, 8, 16, 16), Color::BLACK); + } +} + +TEST_F(LayerTransactionTest, SetCropWithNextResize_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // request setCrop_legacy to be applied with the next resize Transaction() @@ -1302,7 +1640,7 @@ TEST_F(LayerTransactionTest, SetCropWithNextResize) { } // finally resize - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); { SCOPED_TRACE("new crop applied"); auto shot = screenshot(); @@ -1311,10 +1649,45 @@ TEST_F(LayerTransactionTest, SetCropWithNextResize) { } } -TEST_F(LayerTransactionTest, SetCropWithNextResizeScaleToWindow) { +TEST_F(LayerTransactionTest, SetCropWithNextResize_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + // request setCrop_legacy to be applied with the next resize + Transaction().setCrop(layer, Rect(8, 8, 24, 24)).setGeometryAppliesWithResize(layer).apply(); + { + SCOPED_TRACE("set crop 1"); + screenshot()->expectColor(Rect(8, 8, 24, 24), Color::RED); + } + + Transaction().setCrop(layer, Rect(4, 4, 12, 12)).apply(); + { + SCOPED_TRACE("set crop 2"); + screenshot()->expectColor(Rect(4, 4, 12, 12), Color::RED); + } + + Transaction().setSize(layer, 16, 16).apply(); + { + SCOPED_TRACE("resize"); + screenshot()->expectColor(Rect(4, 4, 12, 12), Color::RED); + } + + // finally resize + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 16, 16)); + { + SCOPED_TRACE("new buffer"); + auto shot = screenshot(); + shot->expectColor(Rect(4, 4, 12, 12), Color::RED); + shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK); + } +} + +TEST_F(LayerTransactionTest, SetCropWithNextResizeScaleToWindow_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // setCrop_legacy is not immediate even with SCALE_TO_WINDOW override Transaction() @@ -1332,7 +1705,38 @@ TEST_F(LayerTransactionTest, SetCropWithNextResizeScaleToWindow) { // XXX crop is never latched without other geometry change (b/69315677) Transaction().setPosition(layer, 1, 0).setGeometryAppliesWithResize(layer).apply(); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); + Transaction().setPosition(layer, 0, 0).apply(); + { + SCOPED_TRACE("new crop applied"); + auto shot = screenshot(); + shot->expectColor(Rect(4, 4, 12, 12), Color::RED); + shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK); + } +} + +TEST_F(LayerTransactionTest, SetCropWithNextResizeScaleToWindow_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + // all properties are applied immediate so setGeometryAppliesWithResize has no effect + Transaction() + .setCrop(layer, Rect(4, 4, 12, 12)) + .setSize(layer, 16, 16) + .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW) + .setGeometryAppliesWithResize(layer) + .apply(); + { + SCOPED_TRACE("new crop pending"); + auto shot = screenshot(); + shot->expectColor(Rect(4, 4, 12, 12), Color::RED); + shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK); + } + + Transaction().setPosition(layer, 1, 0).setGeometryAppliesWithResize(layer).apply(); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 16, 16)); Transaction().setPosition(layer, 0, 0).apply(); { SCOPED_TRACE("new crop applied"); @@ -1342,10 +1746,10 @@ TEST_F(LayerTransactionTest, SetCropWithNextResizeScaleToWindow) { } } -TEST_F(LayerTransactionTest, SetFinalCropBasic) { +TEST_F(LayerTransactionTest, SetFinalCropBasic_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); const Rect crop(8, 8, 24, 24); // same as in SetCropBasic @@ -1355,10 +1759,10 @@ TEST_F(LayerTransactionTest, SetFinalCropBasic) { shot->expectBorder(crop, Color::BLACK); } -TEST_F(LayerTransactionTest, SetFinalCropEmpty) { +TEST_F(LayerTransactionTest, SetFinalCropEmpty_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // same as in SetCropEmpty { @@ -1374,10 +1778,10 @@ TEST_F(LayerTransactionTest, SetFinalCropEmpty) { } } -TEST_F(LayerTransactionTest, SetFinalCropOutOfBounds) { +TEST_F(LayerTransactionTest, SetFinalCropOutOfBounds_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // same as in SetCropOutOfBounds Transaction().setFinalCrop_legacy(layer, Rect(-128, -64, 128, 64)).apply(); @@ -1386,10 +1790,10 @@ TEST_F(LayerTransactionTest, SetFinalCropOutOfBounds) { shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } -TEST_F(LayerTransactionTest, SetFinalCropWithTranslation) { +TEST_F(LayerTransactionTest, SetFinalCropWithTranslation_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // final crop is applied post-translation Transaction().setPosition(layer, 16, 16).setFinalCrop_legacy(layer, Rect(8, 8, 24, 24)).apply(); @@ -1398,10 +1802,10 @@ TEST_F(LayerTransactionTest, SetFinalCropWithTranslation) { shot->expectBorder(Rect(16, 16, 24, 24), Color::BLACK); } -TEST_F(LayerTransactionTest, SetFinalCropWithScale) { +TEST_F(LayerTransactionTest, SetFinalCropWithScale_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // final crop is not affected by matrix Transaction() @@ -1413,10 +1817,10 @@ TEST_F(LayerTransactionTest, SetFinalCropWithScale) { shot->expectBorder(Rect(8, 8, 24, 24), Color::BLACK); } -TEST_F(LayerTransactionTest, SetFinalCropWithResize) { +TEST_F(LayerTransactionTest, SetFinalCropWithResize_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // same as in SetCropWithResize Transaction().setFinalCrop_legacy(layer, Rect(8, 8, 24, 24)).setSize(layer, 16, 16).apply(); @@ -1427,7 +1831,7 @@ TEST_F(LayerTransactionTest, SetFinalCropWithResize) { shot->expectBorder(Rect(8, 8, 24, 24), Color::BLACK); } - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); { SCOPED_TRACE("resize applied"); auto shot = screenshot(); @@ -1436,10 +1840,10 @@ TEST_F(LayerTransactionTest, SetFinalCropWithResize) { } } -TEST_F(LayerTransactionTest, SetFinalCropWithNextResize) { +TEST_F(LayerTransactionTest, SetFinalCropWithNextResize_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // same as in SetCropWithNextResize Transaction() @@ -1464,7 +1868,7 @@ TEST_F(LayerTransactionTest, SetFinalCropWithNextResize) { } // finally resize - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); { SCOPED_TRACE("new final crop applied"); auto shot = screenshot(); @@ -1473,10 +1877,10 @@ TEST_F(LayerTransactionTest, SetFinalCropWithNextResize) { } } -TEST_F(LayerTransactionTest, SetFinalCropWithNextResizeScaleToWindow) { +TEST_F(LayerTransactionTest, SetFinalCropWithNextResizeScaleToWindow_BufferQueue) { sp layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); // same as in SetCropWithNextResizeScaleToWindow Transaction() @@ -1494,7 +1898,7 @@ TEST_F(LayerTransactionTest, SetFinalCropWithNextResizeScaleToWindow) { // XXX final crop is never latched without other geometry change (b/69315677) Transaction().setPosition(layer, 1, 0).setGeometryAppliesWithResize(layer).apply(); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); Transaction().setPosition(layer, 0, 0).apply(); { SCOPED_TRACE("new final crop applied"); @@ -1504,6 +1908,282 @@ TEST_F(LayerTransactionTest, SetFinalCropWithNextResizeScaleToWindow) { } } +TEST_F(LayerTransactionTest, SetBufferBasic_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetBufferMultipleBuffers_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + { + SCOPED_TRACE("set buffer 1"); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + } + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLUE, 32, 32)); + + { + SCOPED_TRACE("set buffer 2"); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + } + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + + { + SCOPED_TRACE("set buffer 3"); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + } +} + +TEST_F(LayerTransactionTest, SetBufferMultipleLayers_BufferState) { + sp layer1; + ASSERT_NO_FATAL_FAILURE( + layer1 = createLayer("test", 64, 64, ISurfaceComposerClient::eFXSurfaceBufferState)); + + sp layer2; + ASSERT_NO_FATAL_FAILURE( + layer2 = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::RED, 64, 64)); + + { + SCOPED_TRACE("set layer 1 buffer red"); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 64, 64), Color::RED); + } + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::BLUE, 32, 32)); + + { + SCOPED_TRACE("set layer 2 buffer blue"); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectColor(Rect(0, 32, 64, 64), Color::RED); + shot->expectColor(Rect(0, 32, 32, 64), Color::RED); + } + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::GREEN, 64, 64)); + { + SCOPED_TRACE("set layer 1 buffer green"); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectColor(Rect(0, 32, 64, 64), Color::GREEN); + shot->expectColor(Rect(0, 32, 32, 64), Color::GREEN); + } + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::WHITE, 32, 32)); + + { + SCOPED_TRACE("set layer 2 buffer white"); + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::WHITE); + shot->expectColor(Rect(0, 32, 64, 64), Color::GREEN); + shot->expectColor(Rect(0, 32, 32, 64), Color::GREEN); + } +} + +TEST_F(LayerTransactionTest, SetTransformRotate90_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE)); + + Transaction().setTransform(layer, NATIVE_WINDOW_TRANSFORM_ROT_90).apply(); + + screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::BLUE, Color::RED, Color::WHITE, + Color::GREEN, true /* filtered */); +} + +TEST_F(LayerTransactionTest, SetTransformFlipH_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE)); + + Transaction().setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_H).apply(); + + screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::GREEN, Color::RED, Color::WHITE, + Color::BLUE, true /* filtered */); +} + +TEST_F(LayerTransactionTest, SetTransformFlipV_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE)); + + Transaction().setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_V).apply(); + + screenshot()->expectQuadrant(Rect(0, 0, 32, 32), Color::BLUE, Color::WHITE, Color::RED, + Color::GREEN, true /* filtered */); +} + +TEST_F(LayerTransactionTest, SetTransformToDisplayInverse_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + Transaction().setTransformToDisplayInverse(layer, false).apply(); + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::GREEN, 32, 32)); + + Transaction().setTransformToDisplayInverse(layer, true).apply(); +} + +TEST_F(LayerTransactionTest, SetFenceBasic_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + sp buffer = + new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED); + + sp fence = new Fence(-1); + + Transaction() + .setBuffer(layer, buffer) + .setAcquireFence(layer, fence) + .setSize(layer, 32, 32) + .apply(); + + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetDataspaceBasic_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + sp buffer = + new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED); + + Transaction() + .setBuffer(layer, buffer) + .setDataspace(layer, ui::Dataspace::UNKNOWN) + .setSize(layer, 32, 32) + .apply(); + + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetHdrMetadataBasic_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + sp buffer = + new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED); + + HdrMetadata hdrMetadata; + hdrMetadata.validTypes = 0; + Transaction() + .setBuffer(layer, buffer) + .setHdrMetadata(layer, hdrMetadata) + .setSize(layer, 32, 32) + .apply(); + + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetSurfaceDamageRegionBasic_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + sp buffer = + new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED); + + Region region; + region.set(32, 32); + Transaction() + .setBuffer(layer, buffer) + .setSurfaceDamageRegion(layer, region) + .setSize(layer, 32, 32) + .apply(); + + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetApiBasic_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + sp buffer = + new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED); + + Transaction() + .setBuffer(layer, buffer) + .setApi(layer, NATIVE_WINDOW_API_CPU) + .setSize(layer, 32, 32) + .apply(); + + auto shot = screenshot(); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); +} + +TEST_F(LayerTransactionTest, SetSidebandStreamNull_BufferState) { + sp layer; + ASSERT_NO_FATAL_FAILURE( + layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + + // verify this doesn't cause a crash + Transaction().setSidebandStream(layer, nullptr).apply(); +} + class LayerUpdateTest : public LayerTransactionTest { protected: virtual void SetUp() { @@ -2569,8 +3249,8 @@ TEST_F(ScreenCaptureTest, CaptureCrop) { mComposerClient->createSurface(String8("Blue surface"), 30, 30, PIXEL_FORMAT_RGBA_8888, 0, redLayer.get()); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(redLayer, Color::RED)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(blueLayer, Color::BLUE)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30)); SurfaceComposerClient::Transaction() .setLayer(redLayer, INT32_MAX - 1) @@ -2603,8 +3283,8 @@ TEST_F(ScreenCaptureTest, CaptureSize) { mComposerClient->createSurface(String8("Blue surface"), 30, 30, PIXEL_FORMAT_RGBA_8888, 0, redLayer.get()); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(redLayer, Color::RED)); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(blueLayer, Color::BLUE)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30)); SurfaceComposerClient::Transaction() .setLayer(redLayer, INT32_MAX - 1) @@ -2636,7 +3316,7 @@ TEST_F(ScreenCaptureTest, CaptureInvalidLayer) { sp redLayer = mComposerClient->createSurface(String8("Red surface"), 60, 60, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_NO_FATAL_FAILURE(fillLayerColor(redLayer, Color::RED)); + ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60)); auto redLayerHandle = redLayer->getHandle(); mComposerClient->destroySurface(redLayerHandle); @@ -2655,9 +3335,9 @@ protected: void SetUp() override { LayerTransactionTest::SetUp(); bgLayer = createLayer("BG layer", 20, 20); - fillLayerColor(bgLayer, Color::RED); + fillBufferQueueLayerColor(bgLayer, Color::RED, 20, 20); fgLayer = createLayer("FG layer", 20, 20); - fillLayerColor(fgLayer, Color::BLUE); + fillBufferQueueLayerColor(fgLayer, Color::BLUE, 20, 20); Transaction().setLayer(fgLayer, mLayerZBase + 1).apply(); { SCOPED_TRACE("before anything"); -- cgit v1.2.3-59-g8ed1b From d314f169d79d8a3b1de4289190c3f420188426f6 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Wed, 15 Aug 2018 13:12:42 -0700 Subject: Safe-guard Transaction::merge against programmer error. We can warn on unmerged properties ensuring that this function is updated when new properties are added. Test: None. Change-Id: I718b0e73e8fb5543360ec82a6f0645eb8be8a25c --- libs/gui/LayerState.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 931c446275..05c24c5e1a 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -318,6 +318,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eSidebandStreamChanged; sidebandStream = other.sidebandStream; } + + if (other.what != what) { + ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating?"); + } } }; // namespace android -- cgit v1.2.3-59-g8ed1b From dcce0e2462c9bd0b6ac0db3f95c43cd2b9222eb2 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Thu, 23 Aug 2018 08:35:19 -0700 Subject: SF: Remove setFinalCrop impl 2/2 setFinalCrop functionality is reimplemented by creating a new bounds layer and applying a crop on this layer. see ag/4625718 Test: mmma frameworks/native/services/surfaceflinger/tests/ && \ mmma frameworks/native/libs/gui/tests/ && adb sync data && \ adb shell /data/nativetest64/libgui_test/libgui_test && \ adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest && \ adb shell /data/nativetest64/SurfaceFlinger_test/SurfaceFlinger_test && \ adb shell /data/nativetest64/SurfaceParcelable_test/SurfaceParcelable_test && \ adb shell /data/nativetest64/sffakehwc_test/sffakehwc_test && \ echo "ALL TESTS PASSED" Change-Id: I9be511c07a3351a2947afb2beed10ce2a462b635 --- cmds/surfacereplayer/proto/src/trace.proto | 7 +- cmds/surfacereplayer/replayer/Replayer.cpp | 13 -- cmds/surfacereplayer/replayer/Replayer.h | 2 - libs/gui/LayerDebugInfo.cpp | 5 +- libs/gui/LayerState.cpp | 6 - libs/gui/SurfaceComposerClient.cpp | 12 -- libs/gui/include/gui/LayerDebugInfo.h | 1 - libs/gui/include/gui/LayerState.h | 39 ++-- libs/gui/include/gui/SurfaceComposerClient.h | 1 - services/surfaceflinger/BufferLayer.cpp | 11 -- services/surfaceflinger/BufferStateLayer.h | 2 - services/surfaceflinger/Layer.cpp | 69 +------ services/surfaceflinger/Layer.h | 7 - services/surfaceflinger/LayerRejecter.cpp | 5 - services/surfaceflinger/SurfaceFlinger.cpp | 4 - services/surfaceflinger/SurfaceInterceptor.cpp | 13 -- services/surfaceflinger/SurfaceInterceptor.h | 1 - .../surfaceflinger/layerproto/LayerProtoParser.cpp | 4 +- .../include/layerproto/LayerProtoParser.h | 1 - services/surfaceflinger/layerproto/layers.proto | 2 +- .../tests/SurfaceFlinger_test.filter | 2 +- .../tests/SurfaceInterceptor_test.cpp | 30 --- services/surfaceflinger/tests/Transaction_test.cpp | 216 --------------------- .../tests/fakehwc/SFFakeHwc_test.cpp | 156 --------------- 24 files changed, 24 insertions(+), 585 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto index 0bc08a91ab..68ddeb02d6 100644 --- a/cmds/surfacereplayer/proto/src/trace.proto +++ b/cmds/surfacereplayer/proto/src/trace.proto @@ -30,14 +30,13 @@ message Transaction { message SurfaceChange { required int32 id = 1; - + reserved 7; oneof SurfaceChange { PositionChange position = 2; SizeChange size = 3; AlphaChange alpha = 4; LayerChange layer = 5; CropChange crop = 6; - FinalCropChange final_crop = 7; MatrixChange matrix = 8; OverrideScalingModeChange override_scaling_mode = 9; TransparentRegionHintChange transparent_region_hint = 10; @@ -71,10 +70,6 @@ message CropChange { required Rectangle rectangle = 1; } -message FinalCropChange { - required Rectangle rectangle = 1; -} - message MatrixChange { required float dsdx = 1; required float dtdx = 2; diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp index d9ff4ba59f..66025468ea 100644 --- a/cmds/surfacereplayer/replayer/Replayer.cpp +++ b/cmds/surfacereplayer/replayer/Replayer.cpp @@ -388,9 +388,6 @@ status_t Replayer::doSurfaceTransaction( case SurfaceChange::SurfaceChangeCase::kMatrix: setMatrix(transaction, change.id(), change.matrix()); break; - case SurfaceChange::SurfaceChangeCase::kFinalCrop: - setFinalCrop(transaction, change.id(), change.final_crop()); - break; case SurfaceChange::SurfaceChangeCase::kOverrideScalingMode: setOverrideScalingMode(transaction, change.id(), change.override_scaling_mode()); @@ -492,16 +489,6 @@ void Replayer::setCrop(SurfaceComposerClient::Transaction& t, t.setCrop_legacy(mLayers[id], r); } -void Replayer::setFinalCrop(SurfaceComposerClient::Transaction& t, - layer_id id, const FinalCropChange& fcc) { - ALOGV("Layer %d: Setting Final Crop -- left=%d, top=%d, right=%d, bottom=%d", id, - fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(), - fcc.rectangle().bottom()); - Rect r = Rect(fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(), - fcc.rectangle().bottom()); - t.setFinalCrop_legacy(mLayers[id], r); -} - void Replayer::setMatrix(SurfaceComposerClient::Transaction& t, layer_id id, const MatrixChange& mc) { ALOGV("Layer %d: Setting Matrix -- dsdx=%f, dtdx=%f, dsdy=%f, dtdy=%f", id, mc.dsdx(), diff --git a/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h index 295403eace..68390d33ae 100644 --- a/cmds/surfacereplayer/replayer/Replayer.h +++ b/cmds/surfacereplayer/replayer/Replayer.h @@ -92,8 +92,6 @@ class Replayer { layer_id id, const LayerChange& lc); void setCrop(SurfaceComposerClient::Transaction& t, layer_id id, const CropChange& cc); - void setFinalCrop(SurfaceComposerClient::Transaction& t, - layer_id id, const FinalCropChange& fcc); void setMatrix(SurfaceComposerClient::Transaction& t, layer_id id, const MatrixChange& mc); void setOverrideScalingMode(SurfaceComposerClient::Transaction& t, diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp index d3dc16d30e..ccde9e08e1 100644 --- a/libs/gui/LayerDebugInfo.cpp +++ b/libs/gui/LayerDebugInfo.cpp @@ -42,7 +42,6 @@ status_t LayerDebugInfo::writeToParcel(Parcel* parcel) const { RETURN_ON_ERROR(parcel->writeInt32(mWidth)); RETURN_ON_ERROR(parcel->writeInt32(mHeight)); RETURN_ON_ERROR(parcel->write(mCrop)); - RETURN_ON_ERROR(parcel->write(mFinalCrop)); RETURN_ON_ERROR(parcel->writeFloat(mColor.r)); RETURN_ON_ERROR(parcel->writeFloat(mColor.g)); RETURN_ON_ERROR(parcel->writeFloat(mColor.b)); @@ -81,7 +80,6 @@ status_t LayerDebugInfo::readFromParcel(const Parcel* parcel) { RETURN_ON_ERROR(parcel->readInt32(&mWidth)); RETURN_ON_ERROR(parcel->readInt32(&mHeight)); RETURN_ON_ERROR(parcel->read(mCrop)); - RETURN_ON_ERROR(parcel->read(mFinalCrop)); mColor.r = parcel->readFloat(); RETURN_ON_ERROR(parcel->errorCheck()); mColor.g = parcel->readFloat(); @@ -121,8 +119,7 @@ std::string to_string(const LayerDebugInfo& info) { info.mLayerStack, info.mZ, static_cast(info.mX), static_cast(info.mY), info.mWidth, info.mHeight); - result.appendFormat("crop=%s, finalCrop=%s, ", - to_string(info.mCrop).c_str(), to_string(info.mFinalCrop).c_str()); + result.appendFormat("crop=%s, ", to_string(info.mCrop).c_str()); result.appendFormat("isOpaque=%1d, invalidate=%1d, ", info.mIsOpaque, info.mContentDirty); result.appendFormat("dataspace=%s, ", dataspaceDetails(info.mDataSpace).c_str()); result.appendFormat("pixelformat=%s, ", decodePixelFormat(info.mPixelFormat).c_str()); diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 05c24c5e1a..deb8ea8f7e 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -38,7 +38,6 @@ status_t layer_state_t::write(Parcel& output) const *reinterpret_cast( output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix; output.write(crop_legacy); - output.write(finalCrop_legacy); output.writeStrongBinder(barrierHandle_legacy); output.writeStrongBinder(reparentHandle); output.writeUint64(frameNumber_legacy); @@ -99,7 +98,6 @@ status_t layer_state_t::read(const Parcel& input) return BAD_VALUE; } input.read(crop_legacy); - input.read(finalCrop_legacy); barrierHandle_legacy = input.readStrongBinder(); reparentHandle = input.readStrongBinder(); frameNumber_legacy = input.readUint64(); @@ -248,10 +246,6 @@ void layer_state_t::merge(const layer_state_t& other) { barrierGbp_legacy = other.barrierGbp_legacy; frameNumber_legacy = other.frameNumber_legacy; } - if (other.what & eFinalCropChanged_legacy) { - what |= eFinalCropChanged_legacy; - finalCrop_legacy = other.finalCrop_legacy; - } if (other.what & eOverrideScalingModeChanged) { what |= eOverrideScalingModeChanged; overrideScalingMode = other.overrideScalingMode; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index b8465e37a6..f913977544 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -353,18 +353,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop_ return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFinalCrop_legacy( - const sp& sc, const Rect& crop) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eFinalCropChanged_legacy; - s->finalCrop_legacy = crop; - return *this; -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(const sp& sc, const sp& handle, diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h index 92bd8c5b28..66a7b4dc06 100644 --- a/libs/gui/include/gui/LayerDebugInfo.h +++ b/libs/gui/include/gui/LayerDebugInfo.h @@ -52,7 +52,6 @@ public: int32_t mWidth = -1; int32_t mHeight = -1; Rect mCrop = Rect::INVALID_RECT; - Rect mFinalCrop = Rect::INVALID_RECT; half4 mColor = half4(1.0_hf, 1.0_hf, 1.0_hf, 0.0_hf); uint32_t mFlags = 0; PixelFormat mPixelFormat = PIXEL_FORMAT_NONE; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 098179864a..0859aff8fa 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -54,25 +54,24 @@ struct layer_state_t { eLayerStackChanged = 0x00000080, eCropChanged_legacy = 0x00000100, eDeferTransaction_legacy = 0x00000200, - eFinalCropChanged_legacy = 0x00000400, - eOverrideScalingModeChanged = 0x00000800, - eGeometryAppliesWithResize = 0x00001000, - eReparentChildren = 0x00002000, - eDetachChildren = 0x00004000, - eRelativeLayerChanged = 0x00008000, - eReparent = 0x00010000, - eColorChanged = 0x00020000, - eDestroySurface = 0x00040000, - eTransformChanged = 0x00100000, - eTransformToDisplayInverseChanged = 0x00200000, - eCropChanged = 0x00400000, - eBufferChanged = 0x00800000, - eAcquireFenceChanged = 0x01000000, - eDataspaceChanged = 0x02000000, - eHdrMetadataChanged = 0x04000000, - eSurfaceDamageRegionChanged = 0x08000000, - eApiChanged = 0x10000000, - eSidebandStreamChanged = 0x20000000, + eOverrideScalingModeChanged = 0x00000400, + eGeometryAppliesWithResize = 0x00000800, + eReparentChildren = 0x00001000, + eDetachChildren = 0x00002000, + eRelativeLayerChanged = 0x00004000, + eReparent = 0x00008000, + eColorChanged = 0x00010000, + eDestroySurface = 0x00020000, + eTransformChanged = 0x00040000, + eTransformToDisplayInverseChanged = 0x00080000, + eCropChanged = 0x00100000, + eBufferChanged = 0x00200000, + eAcquireFenceChanged = 0x00400000, + eDataspaceChanged = 0x00800000, + eHdrMetadataChanged = 0x01000000, + eSurfaceDamageRegionChanged = 0x02000000, + eApiChanged = 0x04000000, + eSidebandStreamChanged = 0x08000000, }; layer_state_t() @@ -88,7 +87,6 @@ struct layer_state_t { mask(0), reserved(0), crop_legacy(Rect::INVALID_RECT), - finalCrop_legacy(Rect::INVALID_RECT), frameNumber_legacy(0), overrideScalingMode(-1), transform(0), @@ -126,7 +124,6 @@ struct layer_state_t { uint8_t reserved; matrix22_t matrix; Rect crop_legacy; - Rect finalCrop_legacy; sp barrierHandle_legacy; sp reparentHandle; uint64_t frameNumber_legacy; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 9bd1131ec0..539e46c12d 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -204,7 +204,6 @@ public: Transaction& setMatrix(const sp& sc, float dsdx, float dtdx, float dtdy, float dsdy); Transaction& setCrop_legacy(const sp& sc, const Rect& crop); - Transaction& setFinalCrop_legacy(const sp& sc, const Rect& crop); Transaction& setLayerStack(const sp& sc, uint32_t layerStack); // Defers applying any changes made in this transaction until the Layer // identified by handle reaches the given frameNumber. If the Layer identified diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 3e2fb2e408..0550b3527a 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -589,17 +589,6 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT ui::Transform t = getTransform(); Rect win = bounds; - Rect finalCrop = getFinalCrop(s); - if (!finalCrop.isEmpty()) { - win = t.transform(win); - if (!win.intersect(finalCrop, &win)) { - win.clear(); - } - win = t.inverse().transform(win); - if (!win.intersect(bounds, &win)) { - win.clear(); - } - } float left = float(win.left) / float(getActiveWidth(s)); float top = float(win.top) / float(getActiveHeight(s)); diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 5cc8d567b9..ac3aad14b4 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -58,7 +58,6 @@ public: return s.transparentRegionHint; } Rect getCrop(const Layer::State& s) const; - Rect getFinalCrop(const Layer::State& /*s*/) const { return Rect::EMPTY_RECT; } bool setTransform(uint32_t transform) override; bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; @@ -79,7 +78,6 @@ public: // Override to ignore legacy layer state properties that are not used by BufferStateLayer bool setCrop_legacy(const Rect& /*crop*/, bool /*immediate*/) override { return false; }; - bool setFinalCrop_legacy(const Rect& /*crop*/, bool /*immediate*/) override { return false; }; void deferTransactionUntil_legacy(const sp& /*barrierHandle*/, uint64_t /*frameNumber*/) override {} void deferTransactionUntil_legacy(const sp& /*barrierLayer*/, diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index d2ab1b3d48..edd5cd1716 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -103,8 +103,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n mCurrentState.flags = layerFlags; mCurrentState.active_legacy.transform.set(0, 0); mCurrentState.crop_legacy.makeInvalid(); - mCurrentState.finalCrop_legacy.makeInvalid(); - mCurrentState.requestedFinalCrop_legacy = mCurrentState.finalCrop_legacy; mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy; mCurrentState.z = 0; mCurrentState.color.a = 1.0f; @@ -298,11 +296,6 @@ Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const { ui::Transform t = getTransform(); win = t.transform(win); - Rect finalCrop = getFinalCrop(s); - if (!finalCrop.isEmpty()) { - win.intersect(finalCrop, &win); - } - const sp& p = mDrawingParent.promote(); // Now we need to calculate the parent bounds, so we can clip ourselves to those. // When calculating the parent bounds for purposes of clipping, @@ -351,13 +344,9 @@ FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const { ui::Transform t = s.active_legacy.transform; - if (p != nullptr || !s.finalCrop_legacy.isEmpty()) { + if (p != nullptr) { floatWin = t.transform(floatWin); floatWin = floatWin.intersect(parentBounds); - - if (!s.finalCrop_legacy.isEmpty()) { - floatWin = floatWin.intersect(s.finalCrop_legacy.toFloatRect()); - } floatWin = t.inverse().transform(floatWin); } @@ -388,12 +377,6 @@ Rect Layer::computeInitialCrop(const sp& display) const { if (!activeCrop.intersect(display->getViewport(), &activeCrop)) { activeCrop.clear(); } - Rect finalCrop = getFinalCrop(s); - if (!finalCrop.isEmpty()) { - if (!activeCrop.intersect(finalCrop, &activeCrop)) { - activeCrop.clear(); - } - } const auto& p = mDrawingParent.promote(); if (p != nullptr) { @@ -554,12 +537,6 @@ void Layer::setGeometry(const sp& display, uint32_t z) { // computeBounds returns a FloatRect to provide more accuracy during the // transformation. We then round upon constructing 'frame'. Rect frame{t.transform(computeBounds(activeTransparentRegion))}; - Rect finalCrop = getFinalCrop(s); - if (!finalCrop.isEmpty()) { - if (!frame.intersect(finalCrop, &frame)) { - frame.clear(); - } - } if (!frame.intersect(display->getViewport(), &frame)) { frame.clear(); } @@ -671,10 +648,6 @@ void Layer::updateCursorPosition(const sp& display) { Rect bounds = reduce(win, getActiveTransparentRegion(s)); Rect frame(getTransform().transform(bounds)); frame.intersect(display->getViewport(), &frame); - Rect finalCrop = getFinalCrop(s); - if (!finalCrop.isEmpty()) { - frame.intersect(finalCrop, &frame); - } auto& displayTransform = display->getTransform(); auto position = displayTransform.transform(frame); @@ -780,25 +753,9 @@ bool Layer::getFiltering() const { // local state // ---------------------------------------------------------------------------- -static void boundPoint(vec2* point, const Rect& crop) { - if (point->x < crop.left) { - point->x = crop.left; - } - if (point->x > crop.right) { - point->x = crop.right; - } - if (point->y < crop.top) { - point->y = crop.top; - } - if (point->y > crop.bottom) { - point->y = crop.bottom; - } -} - void Layer::computeGeometry(const RenderArea& renderArea, renderengine::Mesh& mesh, bool useIdentityTransform) const { - const Layer::State& s(getDrawingState()); const ui::Transform renderAreaTransform(renderArea.getTransform()); const uint32_t height = renderArea.getHeight(); FloatRect win = computeBounds(); @@ -816,14 +773,6 @@ void Layer::computeGeometry(const RenderArea& renderArea, rt = layerTransform.transform(rt); } - Rect finalCrop = getFinalCrop(s); - if (!finalCrop.isEmpty()) { - boundPoint(<, finalCrop); - boundPoint(&lb, finalCrop); - boundPoint(&rb, finalCrop); - boundPoint(&rt, finalCrop); - } - renderengine::Mesh::VertexArray position(mesh.getPositionArray()); position[0] = renderAreaTransform.transform(lt); position[1] = renderAreaTransform.transform(lb); @@ -1292,20 +1241,6 @@ bool Layer::setCrop_legacy(const Rect& crop, bool immediate) { return true; } -bool Layer::setFinalCrop_legacy(const Rect& crop, bool immediate) { - if (mCurrentState.requestedFinalCrop_legacy == crop) return false; - mCurrentState.sequence++; - mCurrentState.requestedFinalCrop_legacy = crop; - if (immediate && !mFreezeGeometryUpdates) { - mCurrentState.finalCrop_legacy = crop; - } - mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate; - - mCurrentState.modified = true; - setTransactionFlags(eTransactionNeeded); - return true; -} - bool Layer::setOverrideScalingMode(int32_t scalingMode) { if (scalingMode == mOverrideScalingMode) return false; mOverrideScalingMode = scalingMode; @@ -1417,7 +1352,6 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mWidth = ds.active_legacy.w; info.mHeight = ds.active_legacy.h; info.mCrop = ds.crop_legacy; - info.mFinalCrop = ds.finalCrop_legacy; info.mColor = ds.color; info.mFlags = ds.flags; info.mPixelFormat = getPixelFormat(); @@ -1955,7 +1889,6 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) size->set_h(state.active_legacy.h); LayerProtoHelper::writeToProto(state.crop_legacy, layerInfo->mutable_crop()); - LayerProtoHelper::writeToProto(state.finalCrop_legacy, layerInfo->mutable_final_crop()); layerInfo->set_is_opaque(isOpaque(state)); layerInfo->set_invalidate(contentDirty); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 56261b9268..0a169efb66 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -129,10 +129,6 @@ public: Rect crop_legacy; Rect requestedCrop_legacy; - // finalCrop is expressed in display space coordinate. - Rect finalCrop_legacy; - Rect requestedFinalCrop_legacy; - // If set, defers this state update until the identified Layer // receives a frame with the given frameNumber wp barrierLayer_legacy; @@ -225,8 +221,6 @@ public: virtual bool setPosition(float x, float y, bool immediate); // Buffer space virtual bool setCrop_legacy(const Rect& crop, bool immediate); - // Parent buffer space/display space - virtual bool setFinalCrop_legacy(const Rect& crop, bool immediate); // TODO(b/38182121): Could we eliminate the various latching modes by // using the layer hierarchy? @@ -351,7 +345,6 @@ public: return s.activeTransparentRegion_legacy; } virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; } - virtual Rect getFinalCrop(const Layer::State& s) const { return s.finalCrop_legacy; } protected: /* diff --git a/services/surfaceflinger/LayerRejecter.cpp b/services/surfaceflinger/LayerRejecter.cpp index 136cdc03f7..72abea8b2d 100644 --- a/services/surfaceflinger/LayerRejecter.cpp +++ b/services/surfaceflinger/LayerRejecter.cpp @@ -90,11 +90,6 @@ bool LayerRejecter::reject(const sp& buf, const BufferItem& item) mCurrent.crop_legacy = mFront.requestedCrop_legacy; mRecomputeVisibleRegions = true; } - if (mFront.finalCrop_legacy != mFront.requestedFinalCrop_legacy) { - mFront.finalCrop_legacy = mFront.requestedFinalCrop_legacy; - mCurrent.finalCrop_legacy = mFront.requestedFinalCrop_legacy; - mRecomputeVisibleRegions = true; - } } ALOGD_IF(DEBUG_RESIZE, diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 00e2bbdf39..3c8c92e2fa 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3570,10 +3570,6 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState if (layer->setCrop_legacy(s.crop_legacy, !geometryAppliesWithResize)) flags |= eTraversalNeeded; } - if (what & layer_state_t::eFinalCropChanged_legacy) { - if (layer->setFinalCrop_legacy(s.finalCrop_legacy, !geometryAppliesWithResize)) - flags |= eTraversalNeeded; - } if (what & layer_state_t::eLayerStackChanged) { ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); // We only allow setting layer stacks for top level layers, diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index f504c13a97..0b4c6fcb79 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -113,7 +113,6 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment, layer->mCurrentState.barrierLayer_legacy.promote(), layer->mCurrentState.frameNumber_legacy); } - addFinalCropLocked(transaction, layerId, layer->mCurrentState.finalCrop_legacy); addOverrideScalingModeLocked(transaction, layerId, layer->getEffectiveScalingMode()); addFlagsLocked(transaction, layerId, layer->mCurrentState.flags); } @@ -289,15 +288,6 @@ void SurfaceInterceptor::addCropLocked(Transaction* transaction, int32_t layerId setProtoRectLocked(protoRect, rect); } -void SurfaceInterceptor::addFinalCropLocked(Transaction* transaction, int32_t layerId, - const Rect& rect) -{ - SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); - FinalCropChange* finalCropChange(change->mutable_final_crop()); - Rectangle* protoRect(finalCropChange->mutable_rectangle()); - setProtoRectLocked(protoRect, rect); -} - void SurfaceInterceptor::addDeferTransactionLocked(Transaction* transaction, int32_t layerId, const sp& layer, uint64_t frameNumber) { @@ -374,9 +364,6 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, } addDeferTransactionLocked(transaction, layerId, otherLayer, state.frameNumber_legacy); } - if (state.what & layer_state_t::eFinalCropChanged_legacy) { - addFinalCropLocked(transaction, layerId, state.finalCrop_legacy); - } if (state.what & layer_state_t::eOverrideScalingModeChanged) { addOverrideScalingModeLocked(transaction, layerId, state.overrideScalingMode); } diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h index 218a1d2d22..394b99b415 100644 --- a/services/surfaceflinger/SurfaceInterceptor.h +++ b/services/surfaceflinger/SurfaceInterceptor.h @@ -146,7 +146,6 @@ private: void addCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect); void addDeferTransactionLocked(Transaction* transaction, int32_t layerId, const sp& layer, uint64_t frameNumber); - void addFinalCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect); void addOverrideScalingModeLocked(Transaction* transaction, int32_t layerId, int32_t overrideScalingMode); void addSurfaceChangesLocked(Transaction* transaction, const layer_state_t& state); diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp index e1c0fd340d..a5bf9c16ca 100644 --- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp +++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp @@ -101,7 +101,6 @@ LayerProtoParser::Layer* LayerProtoParser::generateLayer(const LayerProto& layer layerProto.requested_position().y()}; layer->size = {layerProto.size().w(), layerProto.size().h()}; layer->crop = generateRect(layerProto.crop()); - layer->finalCrop = generateRect(layerProto.final_crop()); layer->isOpaque = layerProto.is_opaque(); layer->invalidate = layerProto.invalidate(); layer->dataspace = layerProto.dataspace(); @@ -299,8 +298,7 @@ std::string LayerProtoParser::Layer::to_string() const { z, static_cast(position.x), static_cast(position.y), size.x, size.y); - StringAppendF(&result, "crop=%s, finalCrop=%s, ", crop.to_string().c_str(), - finalCrop.to_string().c_str()); + StringAppendF(&result, "crop=%s, ", crop.to_string().c_str()); StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate); StringAppendF(&result, "dataspace=%s, ", dataspace.c_str()); StringAppendF(&result, "defaultPixelFormat=%s, ", pixelFormat.c_str()); diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h index 360e5997d1..b1610cf9ce 100644 --- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h +++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h @@ -92,7 +92,6 @@ public: float2 requestedPosition; int2 size; LayerProtoParser::Rect crop; - LayerProtoParser::Rect finalCrop; bool isOpaque; bool invalidate; std::string dataspace; diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto index 7f882daa60..2a096345af 100644 --- a/services/surfaceflinger/layerproto/layers.proto +++ b/services/surfaceflinger/layerproto/layers.proto @@ -41,7 +41,7 @@ message LayerProto { // The layer's crop in it's own bounds. optional RectProto crop = 14; // The layer's crop in it's parent's bounds. - optional RectProto final_crop = 15; + optional RectProto final_crop = 15 [deprecated=true]; optional bool is_opaque = 16; optional bool invalidate = 17; optional string dataspace = 18; diff --git a/services/surfaceflinger/tests/SurfaceFlinger_test.filter b/services/surfaceflinger/tests/SurfaceFlinger_test.filter index 1319e12493..34d0fd75f9 100644 --- a/services/surfaceflinger/tests/SurfaceFlinger_test.filter +++ b/services/surfaceflinger/tests/SurfaceFlinger_test.filter @@ -1,5 +1,5 @@ { "presubmit": { - "filter": "CredentialsTest.*:LayerTransactionTest.*:LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*:ScreenCaptureTest.*:DereferenceSurfaceControlTest.*:SurfaceInterceptorTest.*:-CropLatchingTest.FinalCropLatchingBufferOldSize" + "filter": "CredentialsTest.*:LayerTransactionTest.*:LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*:ScreenCaptureTest.*:DereferenceSurfaceControlTest.*:SurfaceInterceptorTest.*" } } diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index 8ac2c87b9e..740d2fa302 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -167,7 +167,6 @@ public: bool alphaUpdateFound(const SurfaceChange& change, bool foundAlpha); bool layerUpdateFound(const SurfaceChange& change, bool foundLayer); bool cropUpdateFound(const SurfaceChange& change, bool foundCrop); - bool finalCropUpdateFound(const SurfaceChange& change, bool foundFinalCrop); bool matrixUpdateFound(const SurfaceChange& change, bool foundMatrix); bool scalingModeUpdateFound(const SurfaceChange& change, bool foundScalingMode); bool transparentRegionHintUpdateFound(const SurfaceChange& change, bool foundTransparentRegion); @@ -199,7 +198,6 @@ public: void alphaUpdate(Transaction&); void layerUpdate(Transaction&); void cropUpdate(Transaction&); - void finalCropUpdate(Transaction&); void matrixUpdate(Transaction&); void overrideScalingModeUpdate(Transaction&); void transparentRegionHintUpdate(Transaction&); @@ -323,10 +321,6 @@ void SurfaceInterceptorTest::cropUpdate(Transaction& t) { t.setCrop_legacy(mBGSurfaceControl, CROP_UPDATE); } -void SurfaceInterceptorTest::finalCropUpdate(Transaction& t) { - t.setFinalCrop_legacy(mBGSurfaceControl, CROP_UPDATE); -} - void SurfaceInterceptorTest::matrixUpdate(Transaction& t) { t.setMatrix(mBGSurfaceControl, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2); } @@ -377,7 +371,6 @@ void SurfaceInterceptorTest::runAllUpdates() { runInTransaction(&SurfaceInterceptorTest::alphaUpdate); runInTransaction(&SurfaceInterceptorTest::layerUpdate); runInTransaction(&SurfaceInterceptorTest::cropUpdate); - runInTransaction(&SurfaceInterceptorTest::finalCropUpdate); runInTransaction(&SurfaceInterceptorTest::matrixUpdate); runInTransaction(&SurfaceInterceptorTest::overrideScalingModeUpdate); runInTransaction(&SurfaceInterceptorTest::transparentRegionHintUpdate); @@ -460,20 +453,6 @@ bool SurfaceInterceptorTest::cropUpdateFound(const SurfaceChange& change, bool f return foundCrop; } -bool SurfaceInterceptorTest::finalCropUpdateFound(const SurfaceChange& change, - bool foundFinalCrop) { - bool hasLeft(change.final_crop().rectangle().left() == CROP_UPDATE.left); - bool hasTop(change.final_crop().rectangle().top() == CROP_UPDATE.top); - bool hasRight(change.final_crop().rectangle().right() == CROP_UPDATE.right); - bool hasBottom(change.final_crop().rectangle().bottom() == CROP_UPDATE.bottom); - if (hasLeft && hasRight && hasTop && hasBottom && !foundFinalCrop) { - foundFinalCrop = true; - } else if (hasLeft && hasRight && hasTop && hasBottom && foundFinalCrop) { - [] () { FAIL(); }(); - } - return foundFinalCrop; -} - bool SurfaceInterceptorTest::matrixUpdateFound(const SurfaceChange& change, bool foundMatrix) { bool hasSx((float)change.matrix().dsdx() == (float)M_SQRT1_2); bool hasTx((float)change.matrix().dtdx() == (float)M_SQRT1_2); @@ -593,9 +572,6 @@ bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace, case SurfaceChange::SurfaceChangeCase::kCrop: foundUpdate = cropUpdateFound(change, foundUpdate); break; - case SurfaceChange::SurfaceChangeCase::kFinalCrop: - foundUpdate = finalCropUpdateFound(change, foundUpdate); - break; case SurfaceChange::SurfaceChangeCase::kMatrix: foundUpdate = matrixUpdateFound(change, foundUpdate); break; @@ -636,7 +612,6 @@ void SurfaceInterceptorTest::assertAllUpdatesFound(const Trace& trace) { ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kAlpha)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kLayer)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kCrop)); - ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kFinalCrop)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kMatrix)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kOverrideScalingMode)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kTransparentRegionHint)); @@ -755,11 +730,6 @@ TEST_F(SurfaceInterceptorTest, InterceptCropUpdateWorks) { captureTest(&SurfaceInterceptorTest::cropUpdate, SurfaceChange::SurfaceChangeCase::kCrop); } -TEST_F(SurfaceInterceptorTest, InterceptFinalCropUpdateWorks) { - captureTest(&SurfaceInterceptorTest::finalCropUpdate, - SurfaceChange::SurfaceChangeCase::kFinalCrop); -} - TEST_F(SurfaceInterceptorTest, InterceptMatrixUpdateWorks) { captureTest(&SurfaceInterceptorTest::matrixUpdate, SurfaceChange::SurfaceChangeCase::kMatrix); } diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 4ab4fec267..ed1529b37b 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -1759,168 +1759,6 @@ TEST_F(LayerTransactionTest, SetCropWithNextResizeScaleToWindow_BufferState) { } } -TEST_F(LayerTransactionTest, SetFinalCropBasic_BufferQueue) { - sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - const Rect crop(8, 8, 24, 24); - - // same as in SetCropBasic - Transaction().setFinalCrop_legacy(layer, crop).apply(); - auto shot = screenshot(); - shot->expectColor(crop, Color::RED); - shot->expectBorder(crop, Color::BLACK); -} - -TEST_F(LayerTransactionTest, SetFinalCropEmpty_BufferQueue) { - sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - - // same as in SetCropEmpty - { - SCOPED_TRACE("empty rect"); - Transaction().setFinalCrop_legacy(layer, Rect(8, 8, 8, 8)).apply(); - screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); - } - - { - SCOPED_TRACE("negative rect"); - Transaction().setFinalCrop_legacy(layer, Rect(8, 8, 0, 0)).apply(); - screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); - } -} - -TEST_F(LayerTransactionTest, SetFinalCropOutOfBounds_BufferQueue) { - sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - - // same as in SetCropOutOfBounds - Transaction().setFinalCrop_legacy(layer, Rect(-128, -64, 128, 64)).apply(); - auto shot = screenshot(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); -} - -TEST_F(LayerTransactionTest, SetFinalCropWithTranslation_BufferQueue) { - sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - - // final crop is applied post-translation - Transaction().setPosition(layer, 16, 16).setFinalCrop_legacy(layer, Rect(8, 8, 24, 24)).apply(); - auto shot = screenshot(); - shot->expectColor(Rect(16, 16, 24, 24), Color::RED); - shot->expectBorder(Rect(16, 16, 24, 24), Color::BLACK); -} - -TEST_F(LayerTransactionTest, SetFinalCropWithScale_BufferQueue) { - sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - - // final crop is not affected by matrix - Transaction() - .setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f) - .setFinalCrop_legacy(layer, Rect(8, 8, 24, 24)) - .apply(); - auto shot = screenshot(); - shot->expectColor(Rect(8, 8, 24, 24), Color::RED); - shot->expectBorder(Rect(8, 8, 24, 24), Color::BLACK); -} - -TEST_F(LayerTransactionTest, SetFinalCropWithResize_BufferQueue) { - sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - - // same as in SetCropWithResize - Transaction().setFinalCrop_legacy(layer, Rect(8, 8, 24, 24)).setSize(layer, 16, 16).apply(); - { - SCOPED_TRACE("resize pending"); - auto shot = screenshot(); - shot->expectColor(Rect(8, 8, 24, 24), Color::RED); - shot->expectBorder(Rect(8, 8, 24, 24), Color::BLACK); - } - - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); - { - SCOPED_TRACE("resize applied"); - auto shot = screenshot(); - shot->expectColor(Rect(8, 8, 16, 16), Color::RED); - shot->expectBorder(Rect(8, 8, 16, 16), Color::BLACK); - } -} - -TEST_F(LayerTransactionTest, SetFinalCropWithNextResize_BufferQueue) { - sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - - // same as in SetCropWithNextResize - Transaction() - .setFinalCrop_legacy(layer, Rect(8, 8, 24, 24)) - .setGeometryAppliesWithResize(layer) - .apply(); - { - SCOPED_TRACE("waiting for next resize"); - screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); - } - - Transaction().setFinalCrop_legacy(layer, Rect(4, 4, 12, 12)).apply(); - { - SCOPED_TRACE("pending final crop modified"); - screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); - } - - Transaction().setSize(layer, 16, 16).apply(); - { - SCOPED_TRACE("resize pending"); - screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED); - } - - // finally resize - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); - { - SCOPED_TRACE("new final crop applied"); - auto shot = screenshot(); - shot->expectColor(Rect(4, 4, 12, 12), Color::RED); - shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK); - } -} - -TEST_F(LayerTransactionTest, SetFinalCropWithNextResizeScaleToWindow_BufferQueue) { - sp layer; - ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - - // same as in SetCropWithNextResizeScaleToWindow - Transaction() - .setFinalCrop_legacy(layer, Rect(4, 4, 12, 12)) - .setSize(layer, 16, 16) - .setOverrideScalingMode(layer, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW) - .setGeometryAppliesWithResize(layer) - .apply(); - { - SCOPED_TRACE("new final crop pending"); - auto shot = screenshot(); - shot->expectColor(Rect(0, 0, 16, 16), Color::RED); - shot->expectBorder(Rect(0, 0, 16, 16), Color::BLACK); - } - - // XXX final crop is never latched without other geometry change (b/69315677) - Transaction().setPosition(layer, 1, 0).setGeometryAppliesWithResize(layer).apply(); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 16, 16)); - Transaction().setPosition(layer, 0, 0).apply(); - { - SCOPED_TRACE("new final crop applied"); - auto shot = screenshot(); - shot->expectColor(Rect(4, 4, 12, 12), Color::RED); - shot->expectBorder(Rect(4, 4, 12, 12), Color::BLACK); - } -} - TEST_F(LayerTransactionTest, SetBufferBasic_BufferState) { sp layer; ASSERT_NO_FATAL_FAILURE( @@ -2346,7 +2184,6 @@ protected: t.setSize(mFGSurfaceControl, 64, 64); t.setPosition(mFGSurfaceControl, 64, 64); t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 64, 64)); - t.setFinalCrop_legacy(mFGSurfaceControl, Rect(0, 0, -1, -1)); }); EXPECT_INITIAL_STATE("After restoring initial state"); @@ -2375,43 +2212,6 @@ protected: } }; -// In this test we ensure that setGeometryAppliesWithResize actually demands -// a buffer of the new size, and not just any size. -TEST_F(CropLatchingTest, FinalCropLatchingBufferOldSize) { - EXPECT_INITIAL_STATE("before anything"); - // Normally the crop applies immediately even while a resize is pending. - asTransaction([&](Transaction& t) { - t.setSize(mFGSurfaceControl, 128, 128); - t.setFinalCrop_legacy(mFGSurfaceControl, Rect(64, 64, 127, 127)); - }); - - EXPECT_CROPPED_STATE("after setting crop (without geometryAppliesWithResize)"); - - restoreInitialState(); - - // In order to prepare to submit a buffer at the wrong size, we acquire it prior to - // initiating the resize. - lockAndFillFGBuffer(); - - asTransaction([&](Transaction& t) { - t.setSize(mFGSurfaceControl, 128, 128); - t.setGeometryAppliesWithResize(mFGSurfaceControl); - t.setFinalCrop_legacy(mFGSurfaceControl, Rect(64, 64, 127, 127)); - }); - - EXPECT_INITIAL_STATE("after setting crop (with geometryAppliesWithResize)"); - - // We now submit our old buffer, at the old size, and ensure it doesn't - // trigger geometry latching. - unlockFGBuffer(); - - EXPECT_INITIAL_STATE("after unlocking FG buffer (with geometryAppliesWithResize)"); - - completeFGResize(); - - EXPECT_CROPPED_STATE("after the resize finishes"); -} - TEST_F(LayerUpdateTest, DeferredTransactionTest) { sp sc; { @@ -2588,22 +2388,6 @@ TEST_F(ChildLayerTest, ChildLayerCropping) { } } -TEST_F(ChildLayerTest, ChildLayerFinalCropping) { - asTransaction([&](Transaction& t) { - t.show(mChild); - t.setPosition(mChild, 0, 0); - t.setPosition(mFGSurfaceControl, 0, 0); - t.setFinalCrop_legacy(mFGSurfaceControl, Rect(0, 0, 5, 5)); - }); - - { - ScreenCapture::captureScreen(&mCapture); - mCapture->expectChildColor(0, 0); - mCapture->expectChildColor(4, 4); - mCapture->expectBGColor(5, 5); - } -} - TEST_F(ChildLayerTest, ChildLayerConstraints) { asTransaction([&](Transaction& t) { t.show(mChild); diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index 7fafab9302..356a880b6e 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -634,40 +634,6 @@ TEST_F(TransactionTest, LayerCrop) { EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); } -TEST_F(TransactionTest, LayerFinalCrop) { - // TODO: Add scaling to confirm that crop happens in display space? - { - TransactionScope ts(*sFakeComposer); - Rect cropRect(32, 32, 32 + 64, 32 + 64); - ts.setFinalCrop_legacy(mFGSurfaceControl, cropRect); - } - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - - // In display space we are cropping with [32, 32, 96, 96] against display rect - // [64, 64, 128, 128]. Should yield display rect [64, 64, 96, 96] - auto referenceFrame = mBaseFrame; - referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 32.f, 32.f}; - referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 32, 64 + 32}; - - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); -} - -TEST_F(TransactionTest, LayerFinalCropEmpty) { - // TODO: Add scaling to confirm that crop happens in display space? - { - TransactionScope ts(*sFakeComposer); - Rect cropRect(16, 16, 32, 32); - ts.setFinalCrop_legacy(mFGSurfaceControl, cropRect); - } - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - - // In display space we are cropping with [16, 16, 32, 32] against display rect - // [64, 64, 128, 128]. The intersection is empty and only the background layer is composited. - std::vector referenceFrame(1); - referenceFrame[BG_LAYER] = mBaseFrame[BG_LAYER]; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); -} - TEST_F(TransactionTest, LayerSetLayer) { { TransactionScope ts(*sFakeComposer); @@ -992,22 +958,6 @@ TEST_F(ChildLayerTest, Cropping) { EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); } -TEST_F(ChildLayerTest, FinalCropping) { - { - TransactionScope ts(*sFakeComposer); - ts.show(mChild); - ts.setPosition(mChild, 0, 0); - ts.setPosition(mFGSurfaceControl, 0, 0); - ts.setFinalCrop_legacy(mFGSurfaceControl, Rect(0, 0, 5, 5)); - } - auto referenceFrame = mBaseFrame; - referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5}; - referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f}; - referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5}; - referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f}; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); -} - TEST_F(ChildLayerTest, Constraints) { { TransactionScope ts(*sFakeComposer); @@ -1354,7 +1304,6 @@ protected: ts.setSize(mFGSurfaceControl, 64, 64); ts.setPosition(mFGSurfaceControl, 64, 64); ts.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 64, 64)); - ts.setFinalCrop_legacy(mFGSurfaceControl, Rect(0, 0, -1, -1)); } }; @@ -1425,111 +1374,6 @@ TEST_F(LatchingTest, CropLatching) { EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame())); } -TEST_F(LatchingTest, FinalCropLatching) { - // Normally the crop applies immediately even while a resize is pending. - { - TransactionScope ts(*sFakeComposer); - ts.setSize(mFGSurfaceControl, 128, 128); - ts.setFinalCrop_legacy(mFGSurfaceControl, Rect(64, 64, 127, 127)); - } - - auto referenceFrame1 = mBaseFrame; - referenceFrame1[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 127, 127}; - referenceFrame1[FG_LAYER].mSourceCrop = - hwc_frect_t{0.f, 0.f, static_cast(127 - 64), static_cast(127 - 64)}; - EXPECT_TRUE(framesAreSame(referenceFrame1, sFakeComposer->getLatestFrame())); - - restoreInitialState(); - - { - TransactionScope ts(*sFakeComposer); - ts.setSize(mFGSurfaceControl, 128, 128); - ts.setGeometryAppliesWithResize(mFGSurfaceControl); - ts.setFinalCrop_legacy(mFGSurfaceControl, Rect(64, 64, 127, 127)); - } - EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); - - completeFGResize(); - - auto referenceFrame2 = mBaseFrame; - referenceFrame2[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 127, 127}; - referenceFrame2[FG_LAYER].mSourceCrop = - hwc_frect_t{0.f, 0.f, static_cast(127 - 64), static_cast(127 - 64)}; - referenceFrame2[FG_LAYER].mSwapCount++; - EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame())); -} - -// In this test we ensure that setGeometryAppliesWithResize actually demands -// a buffer of the new size, and not just any size. -TEST_F(LatchingTest, FinalCropLatchingBufferOldSize) { - // Normally the crop applies immediately even while a resize is pending. - { - TransactionScope ts(*sFakeComposer); - ts.setSize(mFGSurfaceControl, 128, 128); - ts.setFinalCrop_legacy(mFGSurfaceControl, Rect(64, 64, 127, 127)); - } - - auto referenceFrame1 = mBaseFrame; - referenceFrame1[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 127, 127}; - referenceFrame1[FG_LAYER].mSourceCrop = - hwc_frect_t{0.f, 0.f, static_cast(127 - 64), static_cast(127 - 64)}; - EXPECT_TRUE(framesAreSame(referenceFrame1, sFakeComposer->getLatestFrame())); - - restoreInitialState(); - - // In order to prepare to submit a buffer at the wrong size, we acquire it prior to - // initiating the resize. - lockAndFillFGBuffer(); - - { - TransactionScope ts(*sFakeComposer); - ts.setSize(mFGSurfaceControl, 128, 128); - ts.setGeometryAppliesWithResize(mFGSurfaceControl); - ts.setFinalCrop_legacy(mFGSurfaceControl, Rect(64, 64, 127, 127)); - } - EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); - - // We now submit our old buffer, at the old size, and ensure it doesn't - // trigger geometry latching. - unlockFGBuffer(); - - auto referenceFrame2 = mBaseFrame; - referenceFrame2[FG_LAYER].mSwapCount++; - EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame())); - - completeFGResize(); - auto referenceFrame3 = referenceFrame2; - referenceFrame3[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 127, 127}; - referenceFrame3[FG_LAYER].mSourceCrop = - hwc_frect_t{0.f, 0.f, static_cast(127 - 64), static_cast(127 - 64)}; - referenceFrame3[FG_LAYER].mSwapCount++; - EXPECT_TRUE(framesAreSame(referenceFrame3, sFakeComposer->getLatestFrame())); -} - -TEST_F(LatchingTest, FinalCropLatchingRegressionForb37531386) { - // In this scenario, we attempt to set the final crop a second time while the resize - // is still pending, and ensure we are successful. Success meaning the second crop - // is the one which eventually latches and not the first. - { - TransactionScope ts(*sFakeComposer); - ts.setSize(mFGSurfaceControl, 128, 128); - ts.setGeometryAppliesWithResize(mFGSurfaceControl); - ts.setFinalCrop_legacy(mFGSurfaceControl, Rect(64, 64, 127, 127)); - } - - { - TransactionScope ts(*sFakeComposer); - ts.setFinalCrop_legacy(mFGSurfaceControl, Rect(0, 0, -1, -1)); - } - EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); - - completeFGResize(); - - auto referenceFrame = mBaseFrame; - referenceFrame[FG_LAYER].mSwapCount++; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); -} - } // namespace int main(int argc, char** argv) { -- cgit v1.2.3-59-g8ed1b From 217d8e69dcdb217b331fa46e3650924e774a5ac7 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Wed, 12 Sep 2018 16:34:49 -0700 Subject: SF: Fix incorrect LayerState logs Bug: 115559277 Test: logcat Change-Id: If924c60298a0d8fc433d45cdb71d229b57227385 --- libs/gui/LayerState.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index deb8ea8f7e..5a8d8dbc81 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "LayerState" + #include #include #include @@ -313,8 +315,10 @@ void layer_state_t::merge(const layer_state_t& other) { sidebandStream = other.sidebandStream; } - if (other.what != what) { - ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating?"); + if ((other.what & what) != other.what) { + ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " + "other.what=0x%X what=0x%X", + other.what, what); } } -- cgit v1.2.3-59-g8ed1b From d3788632cfc226386f7c7e30612ed2584b6ecb46 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Tue, 18 Sep 2018 16:01:31 -0700 Subject: [SurfaceFlinger] Implement per layer color transformation. Previously we introduced a new composer HAL API to set color transform for per layer and added the plumbing in SurfaceFlinger. This patch implements the functionality and alwasy mark those layers to fall back to GPU composition until composer 2.3 is implemented. BUG: 111562338 Test: Build, boot, flash, tested by setting a greyscale matrix on Settings Test: adb shell /data/nativetest/SurfaceFlinger_test/SurfaceFlinger_test Change-Id: If8d5ed52bf920d8cc962602196fb1b0b6e2955da --- libs/gui/LayerState.cpp | 9 ++++++ libs/gui/SurfaceComposerClient.cpp | 12 +++++++ libs/gui/include/gui/LayerState.h | 6 +++- libs/gui/include/gui/SurfaceComposerClient.h | 4 +++ services/surfaceflinger/BufferLayer.cpp | 1 + services/surfaceflinger/ColorLayer.cpp | 1 + services/surfaceflinger/Layer.cpp | 19 +++++++++++ services/surfaceflinger/Layer.h | 4 +++ services/surfaceflinger/LayerBE.cpp | 14 ++++++++ services/surfaceflinger/LayerBE.h | 1 + .../RenderEngine/gl/GLES20RenderEngine.cpp | 2 +- .../RenderEngine/gl/GLES20RenderEngine.h | 2 +- .../include/renderengine/RenderEngine.h | 5 +-- .../include/renderengine/private/Description.h | 2 ++ services/surfaceflinger/SurfaceFlinger.cpp | 37 ++++++++++++++++++---- services/surfaceflinger/SurfaceFlinger.h | 1 - services/surfaceflinger/tests/Transaction_test.cpp | 28 ++++++++++++++++ .../tests/unittests/CompositionTest.cpp | 2 +- .../unittests/mock/RenderEngine/MockRenderEngine.h | 2 +- 19 files changed, 138 insertions(+), 14 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 5a8d8dbc81..2b0a46181b 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -77,6 +77,9 @@ status_t layer_state_t::write(Parcel& output) const output.writeBool(false); } + memcpy(output.writeInplace(16 * sizeof(float)), + colorTransform.asArray(), 16 * sizeof(float)); + return NO_ERROR; } @@ -130,6 +133,8 @@ status_t layer_state_t::read(const Parcel& input) sidebandStream = NativeHandle::create(input.readNativeHandle(), true); } + colorTransform = mat4(static_cast(input.readInplace(16 * sizeof(float)))); + return NO_ERROR; } @@ -314,6 +319,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eSidebandStreamChanged; sidebandStream = other.sidebandStream; } + if (other.what & eColorTransformChanged) { + what |= eColorTransformChanged; + colorTransform = other.colorTransform; + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 09ea0f601a..1ac96094cc 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -602,6 +602,18 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroyS return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorTransform( + const sp& sc, const mat3& matrix, const vec3& translation) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eColorTransformChanged; + s->colorTransform = mat4(matrix, translation); + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp& token) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 9a9f633ed7..e06e2b14b9 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -72,6 +73,7 @@ struct layer_state_t { eSurfaceDamageRegionChanged = 0x02000000, eApiChanged = 0x04000000, eSidebandStreamChanged = 0x08000000, + eColorTransformChanged = 0x10000000, }; layer_state_t() @@ -94,7 +96,8 @@ struct layer_state_t { crop(Rect::INVALID_RECT), dataspace(ui::Dataspace::UNKNOWN), surfaceDamageRegion(), - api(-1) { + api(-1), + colorTransform(mat4()) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; hdrMetadata.validTypes = 0; @@ -150,6 +153,7 @@ struct layer_state_t { Region surfaceDamageRegion; int32_t api; sp sidebandStream; + mat4 colorTransform; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 314b1182b4..69a759fb4e 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -269,6 +269,10 @@ public: Transaction& destroySurface(const sp& sc); + // Set a color transform matrix on the given layer on the built-in display. + Transaction& setColorTransform(const sp& sc, const mat3& matrix, + const vec3& translation); + status_t setDisplaySurface(const sp& token, const sp& bufferProducer); diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 642ed2fefc..1a73ff0391 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -258,6 +258,7 @@ void BufferLayer::setPerFrameData(const sp& display) { getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace; getBE().compositionInfo.hwc.hdrMetadata = getDrawingHdrMetadata(); getBE().compositionInfo.hwc.supportedPerFrameMetadata = display->getSupportedPerFrameMetadata(); + getBE().compositionInfo.hwc.colorTransform = getColorTransform(); setHwcLayerBuffer(display); } diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index b02c16c595..3a554c9e44 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -75,6 +75,7 @@ void ColorLayer::setPerFrameData(const sp& display) { // Clear out the transform, because it doesn't make sense absent a source buffer getBE().compositionInfo.hwc.transform = HWC2::Transform::None; + getBE().compositionInfo.hwc.colorTransform = getColorTransform(); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index f9bc1e7007..8afd3b3df4 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1546,6 +1546,25 @@ bool Layer::detachChildren() { return true; } +bool Layer::setColorTransform(const mat4& matrix) { + if (mCurrentState.colorTransform == matrix) { + return false; + } + ++mCurrentState.sequence; + mCurrentState.colorTransform = matrix; + setTransactionFlags(eTransactionNeeded); + return true; +} + +const mat4& Layer::getColorTransform() const { + return getDrawingState().colorTransform; +} + +bool Layer::hasColorTransform() const { + static const mat4 identityMatrix = mat4(); + return getDrawingState().colorTransform != identityMatrix; +} + bool Layer::isLegacyDataSpace() const { // return true when no higher bits are set return !(mCurrentDataSpace & (ui::Dataspace::STANDARD_MASK | diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 874b5513e3..4890fa603a 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -181,6 +181,7 @@ public: int32_t api; sp sidebandStream; + mat4 colorTransform; }; explicit Layer(const LayerCreationArgs& args); @@ -255,6 +256,9 @@ public: virtual void setChildrenDrawingParent(const sp& layer); virtual bool reparent(const sp& newParentHandle); virtual bool detachChildren(); + virtual bool setColorTransform(const mat4& matrix); + virtual const mat4& getColorTransform() const; + virtual bool hasColorTransform() const; // Used only to set BufferStateLayer state virtual bool setTransform(uint32_t /*transform*/) { return false; }; diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp index ef017aa9d5..c9b793377a 100644 --- a/services/surfaceflinger/LayerBE.cpp +++ b/services/surfaceflinger/LayerBE.cpp @@ -112,6 +112,20 @@ void CompositionInfo::dumpHwc(std::string& result, const char* tag) const { hwc.surfaceDamage.dump(regionString, "surfaceDamage"); result += regionString.string(); } + + result += base::StringPrintf("\tcolor transform matrix:\n" + "\t\t[%f, %f, %f, %f,\n" + "\t\t %f, %f, %f, %f,\n" + "\t\t %f, %f, %f, %f,\n" + "\t\t %f, %f, %f, %f]\n", + hwc.colorTransform[0][0], hwc.colorTransform[1][0], + hwc.colorTransform[2][0], hwc.colorTransform[3][0], + hwc.colorTransform[0][1], hwc.colorTransform[1][1], + hwc.colorTransform[2][1], hwc.colorTransform[3][1], + hwc.colorTransform[0][2], hwc.colorTransform[1][2], + hwc.colorTransform[2][2], hwc.colorTransform[3][2], + hwc.colorTransform[0][3], hwc.colorTransform[1][3], + hwc.colorTransform[2][3], hwc.colorTransform[3][3]); } void CompositionInfo::dumpRe(std::string& result, const char* tag) const { diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h index 2722b01ea2..d63d16f59e 100644 --- a/services/surfaceflinger/LayerBE.h +++ b/services/surfaceflinger/LayerBE.h @@ -60,6 +60,7 @@ struct CompositionInfo { bool clearClientTarget = false; bool supportedPerFrameMetadata = false; HdrMetadata hdrMetadata; + mat4 colorTransform; } hwc; struct { bool blackoutLayer = false; diff --git a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp index 813c9e60ad..1b0a539f24 100644 --- a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp @@ -743,7 +743,7 @@ void GLES20RenderEngine::setupLayerBlackedOut() { mState.textureEnabled = true; } -void GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) { +void GLES20RenderEngine::setColorTransform(const mat4& colorTransform) { mState.colorMatrix = colorTransform; } diff --git a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h index fa0141046f..4f03a904a9 100644 --- a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h @@ -86,7 +86,7 @@ protected: void setupLayerTexturing(const Texture& texture) override; void setupLayerBlackedOut() override; void setupFillWithColor(float r, float g, float b, float a) override; - void setupColorTransform(const mat4& colorTransform) override; + void setColorTransform(const mat4& colorTransform) override; void disableTexturing() override; void disableBlending() override; diff --git a/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h b/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h index 05668f8ce4..122271f9d6 100644 --- a/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h @@ -115,7 +115,9 @@ public: virtual void setupLayerTexturing(const Texture& texture) = 0; virtual void setupLayerBlackedOut() = 0; virtual void setupFillWithColor(float r, float g, float b, float a) = 0; - virtual void setupColorTransform(const mat4& /* colorTransform */) = 0; + + // Set a color transform matrix that is applied in linear space right before OETF. + virtual void setColorTransform(const mat4& /* colorTransform */) = 0; virtual void disableTexturing() = 0; virtual void disableBlending() = 0; @@ -163,7 +165,6 @@ public: bool useNativeFenceSync() const override; bool useWaitSync() const override; - void setupColorTransform(const mat4& /* colorTransform */) override {} protected: RenderEngine(uint32_t featureFlags); diff --git a/services/surfaceflinger/RenderEngine/include/renderengine/private/Description.h b/services/surfaceflinger/RenderEngine/include/renderengine/private/Description.h index efab8ffb70..911bb7aacd 100644 --- a/services/surfaceflinger/RenderEngine/include/renderengine/private/Description.h +++ b/services/surfaceflinger/RenderEngine/include/renderengine/private/Description.h @@ -68,6 +68,8 @@ struct Description { // projection matrix mat4 projectionMatrix; + + // The color matrix will be applied in linear space right before OETF. mat4 colorMatrix; mat4 inputTransformMatrix; mat4 outputTransformMatrix; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 9410cdb64c..c37b3b19b8 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1604,6 +1604,11 @@ void SurfaceFlinger::calculateWorkingSet() { layer->forceClientComposition(displayId); } + // TODO(b/111562338) remove when composer 2.3 is shipped. + if (layer->hasColorTransform()) { + layer->forceClientComposition(displayId); + } + if (layer->getForceClientComposition(displayId)) { ALOGV("[%s] Requesting Client composition", layer->getName().string()); layer->setCompositionType(displayId, HWC2::Composition::Client); @@ -2141,6 +2146,8 @@ void SurfaceFlinger::configureHwcCommonData(const CompositionInfo& compositionIn ALOGE_IF(error != HWC2::Error::None, "[SF] Failed to set surface damage: %s (%d)", to_string(error).c_str(), static_cast(error)); + + error = (compositionInfo.hwc.hwcLayer)->setColorTransform(compositionInfo.hwc.colorTransform); } void SurfaceFlinger::configureDeviceComposition(const CompositionInfo& compositionInfo) const @@ -3091,6 +3098,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& display) { const bool hasClientComposition = getBE().mHwc->hasClientComposition(displayId); ATRACE_INT("hasClientComposition", hasClientComposition); + mat4 colorMatrix; bool applyColorMatrix = false; bool needsEnhancedColorMatrix = false; @@ -3109,7 +3117,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& display) { const bool skipClientColorTransform = getBE().mHwc->hasCapability( HWC2::Capability::SkipClientColorTransform); - mat4 colorMatrix; + // Compute the global color transform matrix. applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform; if (applyColorMatrix) { colorMatrix = mDrawingState.colorMatrix; @@ -3125,8 +3133,6 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& display) { colorMatrix *= mEnhancedSaturationMatrix; } - getRenderEngine().setupColorTransform(colorMatrix); - if (!display->makeCurrent()) { ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", display->getDisplayName().c_str()); @@ -3205,6 +3211,19 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& display) { break; } case HWC2::Composition::Client: { + if (layer->hasColorTransform()) { + mat4 tmpMatrix; + if (applyColorMatrix) { + tmpMatrix = mDrawingState.colorMatrix; + } + tmpMatrix *= layer->getColorTransform(); + if (needsEnhancedColorMatrix) { + tmpMatrix *= mEnhancedSaturationMatrix; + } + getRenderEngine().setColorTransform(tmpMatrix); + } else { + getRenderEngine().setColorTransform(colorMatrix); + } layer->draw(renderArea, clip); break; } @@ -3217,9 +3236,8 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& display) { firstLayer = false; } - if (applyColorMatrix || needsEnhancedColorMatrix) { - getRenderEngine().setupColorTransform(mat4()); - } + // Clear color transform matrix at the end of the frame. + getRenderEngine().setColorTransform(mat4()); // disable scissor at the end of the frame getBE().mRenderEngine->disableScissor(); @@ -3596,6 +3614,11 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState if (layer->setColor(s.color)) flags |= eTraversalNeeded; } + if (what & layer_state_t::eColorTransformChanged) { + if (layer->setColorTransform(s.colorTransform)) { + flags |= eTraversalNeeded; + } + } if (what & layer_state_t::eMatrixChanged) { // TODO: b/109894387 // @@ -5441,7 +5464,9 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, engine.clearWithColor(0, 0, 0, alpha); traverseLayers([&](Layer* layer) { + engine.setColorTransform(layer->getColorTransform()); layer->draw(renderArea, useIdentityTransform); + engine.setColorTransform(mat4()); }); } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index b77bf48361..3f3086b252 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -454,7 +454,6 @@ private: status_t getCompositionPreference(ui::Dataspace* outDataSpace, ui::PixelFormat* outPixelFormat) const override; - /* ------------------------------------------------------------------------ * DeathRecipient interface */ diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 3af98e5c9b..3166a8c752 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -2064,6 +2064,34 @@ TEST_F(LayerTransactionTest, SetSidebandStreamNull_BufferState) { Transaction().setSidebandStream(layer, nullptr).apply(); } +TEST_F(LayerTransactionTest, SetColorTransformBasic) { + sp colorLayer; + ASSERT_NO_FATAL_FAILURE( + colorLayer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceColor)); + + Transaction().setLayer(colorLayer, mLayerZBase + 1).apply(); + { + SCOPED_TRACE("default color"); + screenshot()->expectColor(Rect(0, 0, 32, 32), Color::BLACK); + } + + const half3 color(50.0f / 255.0f, 100.0f / 255.0f, 150.0f / 255.0f); + const Color expected = {90, 90, 90, 255}; + // this is handwavy, but the precison loss scaled by 255 (8-bit per + // channel) should be less than one + const uint8_t tolerance = 1; + mat3 matrix; + matrix[0][0] = 0.3; matrix[1][0] = 0.59; matrix[2][0] = 0.11; + matrix[0][1] = 0.3; matrix[1][1] = 0.59; matrix[2][1] = 0.11; + matrix[0][2] = 0.3; matrix[1][2] = 0.59; matrix[2][2] = 0.11; + Transaction().setColor(colorLayer, color) + .setColorTransform(colorLayer, matrix, vec3()).apply(); + { + SCOPED_TRACE("new color"); + screenshot()->expectColor(Rect(0, 0, 32, 32), expected, tolerance); + } +} + class LayerUpdateTest : public LayerTransactionTest { protected: virtual void SetUp() { diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 52e64d82ac..3caf1f6823 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -325,7 +325,7 @@ struct BaseDisplayVariant { EXPECT_CALL(*test->mRenderEngine, setOutputDataSpace(ui::Dataspace::UNKNOWN)).Times(1); EXPECT_CALL(*test->mRenderEngine, setDisplayMaxLuminance(DEFAULT_DISPLAY_MAX_LUMINANCE)) .Times(1); - EXPECT_CALL(*test->mRenderEngine, setupColorTransform(_)).Times(2); + EXPECT_CALL(*test->mRenderEngine, setColorTransform(_)).Times(2); // These expectations retire on saturation as the code path these // expectations are for appears to make an extra call to them. // TODO: Investigate this extra call diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h index c29452c0d2..6813cdaa7b 100644 --- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h +++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h @@ -62,7 +62,7 @@ public: MOCK_METHOD1(setupLayerTexturing, void(const Texture&)); MOCK_METHOD0(setupLayerBlackedOut, void()); MOCK_METHOD4(setupFillWithColor, void(float, float, float, float)); - MOCK_METHOD1(setupColorTransform, void(const mat4&)); + MOCK_METHOD1(setColorTransform, void(const mat4&)); MOCK_METHOD1(setSaturationMatrix, void(const mat4&)); MOCK_METHOD0(disableTexturing, void()); MOCK_METHOD0(disableBlending, void()); -- cgit v1.2.3-59-g8ed1b From c837b5ecc406f6bf6e5424d48435b56decbd903e Mon Sep 17 00:00:00 2001 From: Marissa Wall Date: Fri, 12 Oct 2018 10:04:44 -0700 Subject: blast: Send transaction listener from SCC to SF Send the TransactionCompletedListeners to SurfaceFlinger via transactions. The listener will be used to send callbacks after a transaction has completed. Test: Transaction_test Bug: 80477568 Change-Id: I51d3877f2803a192f95db4dd211f48aca9651c30 --- libs/gui/ISurfaceComposer.cpp | 2 +- libs/gui/LayerState.cpp | 19 +++ libs/gui/SurfaceComposerClient.cpp | 131 ++++++++++++++++++++- .../include/gui/ITransactionCompletedListener.h | 18 +++ libs/gui/include/gui/LayerState.h | 4 + libs/gui/include/gui/SurfaceComposerClient.h | 41 ++++++- 6 files changed, 210 insertions(+), 5 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index accf72c390..69e5379047 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -634,10 +634,10 @@ status_t BnSurfaceComposer::onTransact( if (count > data.dataSize()) { return BAD_VALUE; } - ComposerState s; Vector state; state.setCapacity(count); for (size_t i = 0; i < count; i++) { + ComposerState s; if (s.read(data) == BAD_VALUE) { return BAD_VALUE; } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 2b0a46181b..7b71b39ce0 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -80,6 +80,13 @@ status_t layer_state_t::write(Parcel& output) const memcpy(output.writeInplace(16 * sizeof(float)), colorTransform.asArray(), 16 * sizeof(float)); + if (output.writeVectorSize(listenerCallbacks) == NO_ERROR) { + for (const auto& [listener, callbackIds] : listenerCallbacks) { + output.writeStrongBinder(IInterface::asBinder(listener)); + output.writeInt64Vector(callbackIds); + } + } + return NO_ERROR; } @@ -135,6 +142,14 @@ status_t layer_state_t::read(const Parcel& input) colorTransform = mat4(static_cast(input.readInplace(16 * sizeof(float)))); + int32_t listenersSize = input.readInt32(); + for (int32_t i = 0; i < listenersSize; i++) { + auto listener = interface_cast(input.readStrongBinder()); + std::vector callbackIds; + input.readInt64Vector(&callbackIds); + listenerCallbacks.emplace_back(listener, callbackIds); + } + return NO_ERROR; } @@ -323,6 +338,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eColorTransformChanged; colorTransform = other.colorTransform; } + if (other.what & eListenerCallbacksChanged) { + what |= eListenerCallbacksChanged; + listenerCallbacks = other.listenerCallbacks; + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 84df7a9a3d..88c574286b 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -104,13 +104,23 @@ void ComposerService::composerServiceDied() // to be able to return a sp<> to its instance to pass to SurfaceFlinger. // ANDROID_SINGLETON_STATIC_INSTANCE only allows a reference to an instance. +// 0 is an invalid callback id +TransactionCompletedListener::TransactionCompletedListener() : mCallbackIdCounter(1) {} + +CallbackId TransactionCompletedListener::getNextIdLocked() { + return mCallbackIdCounter++; +} + sp TransactionCompletedListener::getInstance() { static sp sInstance = new TransactionCompletedListener; return sInstance; } -void TransactionCompletedListener::startListening() { - std::lock_guard lock(mMutex); +sp TransactionCompletedListener::getIInstance() { + return static_cast>(getInstance()); +} + +void TransactionCompletedListener::startListeningLocked() { if (mListening) { return; } @@ -118,6 +128,16 @@ void TransactionCompletedListener::startListening() { mListening = true; } +CallbackId TransactionCompletedListener::addCallback( + const TransactionCompletedCallbackWithContext& callback) { + std::lock_guard lock(mMutex); + startListeningLocked(); + + CallbackId callbackId = getNextIdLocked(); + mCallbacks.emplace(callbackId, callback); + return callbackId; +} + void TransactionCompletedListener::onTransactionCompleted() { return; } @@ -153,6 +173,17 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr } other.mDisplayStates.clear(); + for (const auto& [listener, callbackInfo] : other.mListenerCallbacks) { + auto& [callbackIds, surfaceControls] = callbackInfo; + mListenerCallbacks[listener].callbackIds.insert(std::make_move_iterator( + callbackIds.begin()), + std::make_move_iterator(callbackIds.end())); + mListenerCallbacks[listener] + .surfaceControls.insert(std::make_move_iterator(surfaceControls.begin()), + std::make_move_iterator(surfaceControls.end())); + } + other.mListenerCallbacks.clear(); + return *this; } @@ -163,6 +194,26 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { sp sf(ComposerService::getComposerService()); + // For every listener with registered callbacks + for (const auto& [listener, callbackInfo] : mListenerCallbacks) { + auto& [callbackIds, surfaceControls] = callbackInfo; + if (callbackIds.empty()) { + continue; + } + + // If the listener has any SurfaceControls set on this Transaction update the surface state + for (const auto& surfaceControl : surfaceControls) { + layer_state_t* s = getLayerState(surfaceControl); + if (!s) { + ALOGE("failed to get layer state"); + continue; + } + s->what |= layer_state_t::eListenerCallbacksChanged; + s->listenerCallbacks.emplace_back(listener, std::move(callbackIds)); + } + } + mListenerCallbacks.clear(); + Vector composerStates; Vector displayStates; uint32_t flags = 0; @@ -232,6 +283,11 @@ layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp& sc) { + mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls.insert(sc); +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( const sp& sc, float x, float y) { layer_state_t* s = getLayerState(sc); @@ -242,6 +298,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosit s->what |= layer_state_t::ePositionChanged; s->x = x; s->y = y; + + registerSurfaceControlForCallback(sc); return *this; } @@ -266,6 +324,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSize( s->w = w; s->h = h; + registerSurfaceControlForCallback(sc); return *this; } @@ -278,6 +337,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer } s->what |= layer_state_t::eLayerChanged; s->z = z; + + registerSurfaceControlForCallback(sc); return *this; } @@ -290,6 +351,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelat s->what |= layer_state_t::eRelativeLayerChanged; s->relativeLayerHandle = relativeTo; s->z = z; + + registerSurfaceControlForCallback(sc); return *this; } @@ -309,6 +372,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags s->flags &= ~mask; s->flags |= (flags & mask); s->mask |= mask; + + registerSurfaceControlForCallback(sc); return *this; } @@ -322,6 +387,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrans } s->what |= layer_state_t::eTransparentRegionChanged; s->transparentRegion = transparentRegion; + + registerSurfaceControlForCallback(sc); return *this; } @@ -334,6 +401,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha } s->what |= layer_state_t::eAlphaChanged; s->alpha = alpha; + + registerSurfaceControlForCallback(sc); return *this; } @@ -346,6 +415,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer } s->what |= layer_state_t::eLayerStackChanged; s->layerStack = layerStack; + + registerSurfaceControlForCallback(sc); return *this; } @@ -364,6 +435,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMatri matrix.dsdy = dsdy; matrix.dtdy = dtdy; s->matrix = matrix; + + registerSurfaceControlForCallback(sc); return *this; } @@ -376,6 +449,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop_ } s->what |= layer_state_t::eCropChanged_legacy; s->crop_legacy = crop; + + registerSurfaceControlForCallback(sc); return *this; } @@ -391,6 +466,8 @@ SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(const spwhat |= layer_state_t::eDeferTransaction_legacy; s->barrierHandle_legacy = handle; s->frameNumber_legacy = frameNumber; + + registerSurfaceControlForCallback(sc); return *this; } @@ -406,6 +483,8 @@ SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(const spwhat |= layer_state_t::eDeferTransaction_legacy; s->barrierGbp_legacy = barrierSurface->getIGraphicBufferProducer(); s->frameNumber_legacy = frameNumber; + + registerSurfaceControlForCallback(sc); return *this; } @@ -419,6 +498,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent } s->what |= layer_state_t::eReparentChildren; s->reparentHandle = newParentHandle; + + registerSurfaceControlForCallback(sc); return *this; } @@ -432,6 +513,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent } s->what |= layer_state_t::eReparent; s->parentHandleForChild = newParentHandle; + + registerSurfaceControlForCallback(sc); return *this; } @@ -445,6 +528,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColor } s->what |= layer_state_t::eColorChanged; s->color = color; + + registerSurfaceControlForCallback(sc); return *this; } @@ -457,6 +542,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrans } s->what |= layer_state_t::eTransformChanged; s->transform = transform; + + registerSurfaceControlForCallback(sc); return *this; } @@ -470,6 +557,8 @@ SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const spwhat |= layer_state_t::eTransformToDisplayInverseChanged; s->transformToDisplayInverse = transformToDisplayInverse; + + registerSurfaceControlForCallback(sc); return *this; } @@ -482,6 +571,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop( } s->what |= layer_state_t::eCropChanged; s->crop = crop; + + registerSurfaceControlForCallback(sc); return *this; } @@ -494,6 +585,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe } s->what |= layer_state_t::eBufferChanged; s->buffer = buffer; + + registerSurfaceControlForCallback(sc); return *this; } @@ -506,6 +599,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAcqui } s->what |= layer_state_t::eAcquireFenceChanged; s->acquireFence = fence; + + registerSurfaceControlForCallback(sc); return *this; } @@ -518,6 +613,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDatas } s->what |= layer_state_t::eDataspaceChanged; s->dataspace = dataspace; + + registerSurfaceControlForCallback(sc); return *this; } @@ -530,6 +627,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setHdrMe } s->what |= layer_state_t::eHdrMetadataChanged; s->hdrMetadata = hdrMetadata; + + registerSurfaceControlForCallback(sc); return *this; } @@ -542,6 +641,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSurfa } s->what |= layer_state_t::eSurfaceDamageRegionChanged; s->surfaceDamageRegion = surfaceDamageRegion; + + registerSurfaceControlForCallback(sc); return *this; } @@ -554,6 +655,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApi( } s->what |= layer_state_t::eApiChanged; s->api = api; + + registerSurfaceControlForCallback(sc); return *this; } @@ -566,6 +669,22 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSideb } s->what |= layer_state_t::eSidebandStreamChanged; s->sidebandStream = sidebandStream; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::addTransactionCompletedCallback( + TransactionCompletedCallback callback, void* callbackContext) { + auto listener = TransactionCompletedListener::getInstance(); + + auto callbackWithContext = std::bind(callback, callbackContext); + + CallbackId callbackId = listener->addCallback(callbackWithContext); + + mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace( + callbackId); return *this; } @@ -576,6 +695,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::detachCh mStatus = BAD_INDEX; } s->what |= layer_state_t::eDetachChildren; + + registerSurfaceControlForCallback(sc); return *this; } @@ -603,6 +724,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setOverr s->what |= layer_state_t::eOverrideScalingModeChanged; s->overrideScalingMode = overrideScalingMode; + + registerSurfaceControlForCallback(sc); return *this; } @@ -614,6 +737,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeome return *this; } s->what |= layer_state_t::eGeometryAppliesWithResize; + + registerSurfaceControlForCallback(sc); return *this; } @@ -637,6 +762,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColor } s->what |= layer_state_t::eColorTransformChanged; s->colorTransform = mat4(matrix, translation); + + registerSurfaceControlForCallback(sc); return *this; } diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h index cdc6a7e187..0a61cd1c9b 100644 --- a/libs/gui/include/gui/ITransactionCompletedListener.h +++ b/libs/gui/include/gui/ITransactionCompletedListener.h @@ -20,6 +20,7 @@ #include #include +#include namespace android { @@ -39,4 +40,21 @@ public: uint32_t flags = 0) override; }; +using CallbackId = int64_t; + +class ListenerCallbacks { +public: + ListenerCallbacks(const sp& listener, + const std::unordered_set& callbacks) + : transactionCompletedListener(listener), + callbackIds(callbacks.begin(), callbacks.end()) {} + + ListenerCallbacks(const sp& listener, + const std::vector& ids) + : transactionCompletedListener(listener), callbackIds(ids) {} + + sp transactionCompletedListener; + std::vector callbackIds; +}; + } // namespace android diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index e06e2b14b9..ddbac7bf47 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -74,6 +75,7 @@ struct layer_state_t { eApiChanged = 0x04000000, eSidebandStreamChanged = 0x08000000, eColorTransformChanged = 0x10000000, + eListenerCallbacksChanged = 0x20000000, }; layer_state_t() @@ -154,6 +156,8 @@ struct layer_state_t { int32_t api; sp sidebandStream; mat4 colorTransform; + + std::vector listenerCallbacks; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 8dcb8c9f33..2ed4f8f3e4 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -19,7 +19,9 @@ #include #include +#include #include +#include #include @@ -50,17 +52,29 @@ class Region; // --------------------------------------------------------------------------- +using TransactionCompletedCallback = std::function; +using TransactionCompletedCallbackWithContext = std::function; + class TransactionCompletedListener : public BnTransactionCompletedListener { - TransactionCompletedListener() = default; + TransactionCompletedListener(); + + CallbackId getNextIdLocked() REQUIRES(mMutex); std::mutex mMutex; bool mListening GUARDED_BY(mMutex) = false; + CallbackId mCallbackIdCounter GUARDED_BY(mMutex) = 1; + + std::map mCallbacks GUARDED_BY(mMutex); + public: static sp getInstance(); + static sp getIInstance(); - void startListening(); + void startListeningLocked() REQUIRES(mMutex); + + CallbackId addCallback(const TransactionCompletedCallbackWithContext& callback); // Overrides BnTransactionCompletedListener's onTransactionCompleted void onTransactionCompleted() override; @@ -177,9 +191,27 @@ public: } }; + struct TCLHash { + std::size_t operator()(const sp& tcl) const { + return std::hash{}((tcl) ? IInterface::asBinder(tcl).get() : nullptr); + } + }; + + struct CallbackInfo { + // All the callbacks that have been requested for a TransactionCompletedListener in the + // Transaction + std::unordered_set callbackIds; + // All the SurfaceControls that have been modified in this TransactionCompletedListener's + // process that require a callback if there is one or more callbackIds set. + std::unordered_set, SCHash> surfaceControls; + }; + class Transaction { std::unordered_map, ComposerState, SCHash> mComposerStates; SortedVector mDisplayStates; + std::unordered_map, CallbackInfo, TCLHash> + mListenerCallbacks; + uint32_t mForceSynchronous = 0; uint32_t mTransactionNestCount = 0; bool mAnimation = false; @@ -190,6 +222,8 @@ public: layer_state_t* getLayerState(const sp& sc); DisplayState& getDisplayState(const sp& token); + void registerSurfaceControlForCallback(const sp& sc); + public: Transaction() = default; virtual ~Transaction() = default; @@ -269,6 +303,9 @@ public: Transaction& setSidebandStream(const sp& sc, const sp& sidebandStream); + Transaction& addTransactionCompletedCallback(TransactionCompletedCallback callback, + void* callbackContext); + // Detaches all child surfaces (and their children recursively) // from their SurfaceControl. // The child SurfaceControls will not throw exceptions or return errors, -- cgit v1.2.3-59-g8ed1b From 2c358bf8206d591a4707d33fd2ca45f0dc5360f7 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Wed, 8 Aug 2018 15:58:15 -0700 Subject: Add setInputWindowInfo to SurfaceComposerClient::Transaction In preparation for passing input through SurfaceFlinger to the InputDispatcher. Bug: 80101428 Bug: 113136004 Bug: 111440400 Change-Id: I5f67fbb9894136bfb16c718ffe1cc23a02f3414d --- include/input/Input.h | 2 ++ include/input/InputTransport.h | 2 ++ libs/gui/Android.bp | 4 +++- libs/gui/LayerState.cpp | 15 +++++++++++++++ libs/gui/SurfaceComposerClient.cpp | 19 +++++++++++++++++++ libs/gui/include/gui/LayerState.h | 9 +++++++++ libs/gui/include/gui/SurfaceComposerClient.h | 4 ++++ 7 files changed, 54 insertions(+), 1 deletion(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/include/input/Input.h b/include/input/Input.h index 819a89f37c..d35354b0f6 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -17,6 +17,8 @@ #ifndef _LIBINPUT_INPUT_H #define _LIBINPUT_INPUT_H +#pragma GCC system_header + /** * Native input event structures. */ diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index 4782c9b237..4c91427a77 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -17,6 +17,8 @@ #ifndef _LIBINPUT_INPUT_TRANSPORT_H #define _LIBINPUT_INPUT_TRANSPORT_H +#pragma GCC system_header + /** * Native input transport. * diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 7677c3a919..127fcd618b 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -135,6 +135,7 @@ cc_library_shared { "libutils", "libnativewindow", "liblog", + "libinput", "libhidlbase", "libhidltransport", "android.hidl.token@1.0-utils", @@ -146,7 +147,7 @@ cc_library_shared { // bufferhub is not used when building libgui for vendors target: { vendor: { - cflags: ["-DNO_BUFFERHUB"], + cflags: ["-DNO_BUFFERHUB", "-DNO_INPUT"], exclude_srcs: [ "BufferHubConsumer.cpp", "BufferHubProducer.cpp", @@ -155,6 +156,7 @@ cc_library_shared { "libbufferhub", "libbufferhubqueue", "libpdx_default_transport", + "libinput" ], }, }, diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 7b71b39ce0..9f30060467 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -50,6 +50,9 @@ status_t layer_state_t::write(Parcel& output) const output.writeFloat(color.r); output.writeFloat(color.g); output.writeFloat(color.b); +#ifndef NO_INPUT + inputInfo.write(output); +#endif output.write(transparentRegion); output.writeUint32(transform); output.writeBool(transformToDisplayInverse); @@ -120,6 +123,11 @@ status_t layer_state_t::read(const Parcel& input) color.r = input.readFloat(); color.g = input.readFloat(); color.b = input.readFloat(); + +#ifndef NO_INPUT + inputInfo = InputWindowInfo::read(input); +#endif + input.read(transparentRegion); transform = input.readUint32(); transformToDisplayInverse = input.readBool(); @@ -343,6 +351,13 @@ void layer_state_t::merge(const layer_state_t& other) { listenerCallbacks = other.listenerCallbacks; } +#ifndef NO_INPUT + if (other.what & eInputInfoChanged) { + what |= eInputInfoChanged; + inputInfo = other.inputInfo; + } +#endif + if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%X what=0x%X", diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index e10bda485b..87c6f27c57 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -42,6 +42,10 @@ #include #include +#ifndef NO_INPUT +#include