diff options
| -rw-r--r-- | libs/gui/include/gui/ISurfaceComposer.h | 21 | ||||
| -rw-r--r-- | libs/gui/include/gui/LayerState.h | 14 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 106 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 9 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/RenderArea.cpp | 34 | ||||
| -rw-r--r-- | services/surfaceflinger/RenderArea.h | 70 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 162 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h | 11 |
12 files changed, 255 insertions, 189 deletions
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 99a3a75502..5f7980413c 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -174,8 +174,25 @@ public: virtual status_t setActiveColorMode(const sp<IBinder>& display, ui::ColorMode colorMode) = 0; - /* Capture the specified screen. requires READ_FRAME_BUFFER permission - * This function will fail if there is a secure window on screen. + /** + * Capture the specified screen. This requires READ_FRAME_BUFFER + * permission. This function will fail if there is a secure window on + * screen. + * + * This function can capture a subregion (the source crop) of the screen. + * The subregion can be optionally rotated. It will also be scaled to + * match the size of the output buffer. + * + * At the moment, sourceCrop is ignored and is always set to the visible + * region (projected display viewport) of the screen. + * + * reqWidth and reqHeight specifies the size of the buffer. When either + * of them is 0, they are set to the size of the logical display viewport. + * + * When useIdentityTransform is true, layer transformations are disabled. + * + * rotation specifies the rotation of the source crop (and the pixels in + * it) around its center. */ virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 788962e490..38de701b16 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -152,10 +152,24 @@ struct DisplayState { sp<IBinder> token; sp<IGraphicBufferProducer> surface; uint32_t layerStack; + + // These states define how layers are projected onto the physical display. + // + // Layers are first clipped to `viewport'. They are then translated and + // scaled from `viewport' to `frame'. Finally, they are rotated according + // to `orientation', `width', and `height'. + // + // For example, assume viewport is Rect(0, 0, 200, 100), frame is Rect(20, + // 10, 420, 210), and the size of the display is WxH. When orientation is + // 0, layers will be scaled by a factor of 2 and translated by (20, 10). + // When orientation is 1, layers will be additionally rotated by 90 + // degrees around the origin clockwise and translated by (W, 0). uint32_t orientation; Rect viewport; Rect frame; + uint32_t width, height; + status_t write(Parcel& output) const; status_t read(const Parcel& input); }; diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index f5b5eda9ec..707cb42336 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -204,7 +204,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, if (!blackOutLayer) { // TODO: we could be more subtle with isFixedSize() - const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize(); + const bool useFiltering = needsFiltering(renderArea) || isFixedSize(); // Query the texture matrix given our current filtering mode. float textureMatrix[16]; diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 309fd0a791..65c3839141 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -224,6 +224,7 @@ DisplayDevice::DisplayDevice( std::unique_ptr<RE::Surface> renderSurface, int displayWidth, int displayHeight, + int displayInstallOrientation, bool hasWideColorGamut, const HdrCapabilities& hdrCapabilities, const int32_t supportedPerFrameMetadata, @@ -239,6 +240,7 @@ DisplayDevice::DisplayDevice( mSurface{std::move(renderSurface)}, mDisplayWidth(displayWidth), mDisplayHeight(displayHeight), + mDisplayInstallOrientation(displayInstallOrientation), mPageFlipCount(0), mIsSecure(isSecure), mLayerStack(NO_LAYER_STACK), @@ -610,9 +612,8 @@ void DisplayDevice::setProjection(int orientation, // need to take care of primary display rotation for mGlobalTransform // for case if the panel is not installed aligned with device orientation if (mType == DisplayType::DISPLAY_PRIMARY) { - int primaryDisplayOrientation = mFlinger->getPrimaryDisplayOrientation(); DisplayDevice::orientationToTransfrom( - (orientation + primaryDisplayOrientation) % (DisplayState::eOrientation270 + 1), + (orientation + mDisplayInstallOrientation) % (DisplayState::eOrientation270 + 1), w, h, &R); } diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 6c3bd91793..3cf06bceaf 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -25,7 +25,7 @@ #include <math/mat4.h> #include <binder/IBinder.h> -#include <gui/ISurfaceComposer.h> +#include <gui/LayerState.h> #include <hardware/hwcomposer_defs.h> #include <ui/GraphicTypes.h> #include <ui/HdrCapabilities.h> @@ -88,6 +88,7 @@ public: std::unique_ptr<RE::Surface> renderSurface, int displayWidth, int displayHeight, + int displayInstallOrientation, bool hasWideColorGamut, const HdrCapabilities& hdrCapabilities, const int32_t supportedPerFrameMetadata, @@ -111,6 +112,7 @@ public: int getWidth() const; int getHeight() const; + int getInstallOrientation() const { return mDisplayInstallOrientation; } void setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers); const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const; @@ -234,6 +236,7 @@ private: std::unique_ptr<RE::Surface> mSurface; int mDisplayWidth; int mDisplayHeight; + const int mDisplayInstallOrientation; mutable uint32_t mPageFlipCount; String8 mDisplayName; bool mIsSecure; @@ -337,23 +340,108 @@ struct DisplayDeviceState { class DisplayRenderArea : public RenderArea { public: DisplayRenderArea(const sp<const DisplayDevice> device, - ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone) - : DisplayRenderArea(device, device->getBounds(), device->getHeight(), device->getWidth(), + Transform::orientation_flags rotation = Transform::ROT_0) + : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(), rotation) {} - DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqHeight, - uint32_t reqWidth, ISurfaceComposer::Rotation rotation) - : RenderArea(reqHeight, reqWidth, CaptureFill::OPAQUE, rotation), mDevice(device), - mSourceCrop(sourceCrop) {} + DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth, + uint32_t reqHeight, Transform::orientation_flags rotation) + : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, + getDisplayRotation(rotation, device->getInstallOrientation())), + mDevice(device), + mSourceCrop(sourceCrop) {} const Transform& getTransform() const override { return mDevice->getTransform(); } Rect getBounds() const override { return mDevice->getBounds(); } int getHeight() const override { return mDevice->getHeight(); } int getWidth() const override { return mDevice->getWidth(); } bool isSecure() const override { return mDevice->isSecure(); } - bool needsFiltering() const override { return mDevice->needsFiltering(); } - Rect getSourceCrop() const override { return mSourceCrop; } + + bool needsFiltering() const override { + // check if the projection from the logical display to the physical + // display needs filtering + if (mDevice->needsFiltering()) { + return true; + } + + // check if the projection from the logical render area (i.e., the + // physical display) to the physical render area requires filtering + const Rect sourceCrop = getSourceCrop(); + int width = sourceCrop.width(); + int height = sourceCrop.height(); + if (getRotationFlags() & Transform::ROT_90) { + std::swap(width, height); + } + return width != getReqWidth() || height != getReqHeight(); + } + + Rect getSourceCrop() const override { + // use the (projected) logical display viewport by default + if (mSourceCrop.isEmpty()) { + return mDevice->getScissor(); + } + + const int orientation = mDevice->getInstallOrientation(); + if (orientation == DisplayState::eOrientationDefault) { + return mSourceCrop; + } + + // Install orientation is transparent to the callers. Apply it now. + uint32_t flags = 0x00; + switch (orientation) { + case DisplayState::eOrientation90: + flags = Transform::ROT_90; + break; + case DisplayState::eOrientation180: + flags = Transform::ROT_180; + break; + case DisplayState::eOrientation270: + flags = Transform::ROT_270; + break; + } + Transform tr; + tr.set(flags, getWidth(), getHeight()); + return tr.transform(mSourceCrop); + } private: + // Install orientation is transparent to the callers. We need to cancel + // it out by modifying rotation flags. + static Transform::orientation_flags getDisplayRotation( + Transform::orientation_flags rotation, int orientation) { + if (orientation == DisplayState::eOrientationDefault) { + return rotation; + } + + // convert hw orientation into flag presentation + // here inverse transform needed + uint8_t hw_rot_90 = 0x00; + uint8_t hw_flip_hv = 0x00; + switch (orientation) { + case DisplayState::eOrientation90: + hw_rot_90 = Transform::ROT_90; + hw_flip_hv = Transform::ROT_180; + break; + case DisplayState::eOrientation180: + hw_flip_hv = Transform::ROT_180; + break; + case DisplayState::eOrientation270: + hw_rot_90 = Transform::ROT_90; + break; + } + + // transform flags operation + // 1) flip H V if both have ROT_90 flag + // 2) XOR these flags + uint8_t rotation_rot_90 = rotation & Transform::ROT_90; + uint8_t rotation_flip_hv = rotation & Transform::ROT_180; + if (rotation_rot_90 & hw_rot_90) { + rotation_flip_hv = (~rotation_flip_hv) & Transform::ROT_180; + } + + return static_cast<Transform::orientation_flags>( + (rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv)); + } + const sp<const DisplayDevice> mDevice; const Rect mSourceCrop; }; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 0caac9b16d..72f1fc4363 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -88,7 +88,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& n mCurrentOpacity(true), mCurrentFrameNumber(0), mFrameLatencyNeeded(false), - mFiltering(false), mNeedsFiltering(false), mProtectedByApp(false), mClientRef(client), @@ -793,14 +792,6 @@ bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) { return true; } -void Layer::setFiltering(bool filtering) { - mFiltering = filtering; -} - -bool Layer::getFiltering() const { - return mFiltering; -} - // ---------------------------------------------------------------------------- // local state // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 301f190e16..239f3979e8 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -530,9 +530,6 @@ public: // ----------------------------------------------------------------------- void clearWithOpenGL(const RenderArea& renderArea) const; - void setFiltering(bool filtering); - bool getFiltering() const; - inline const State& getDrawingState() const { return mDrawingState; } inline const State& getCurrentState() const { return mCurrentState; } @@ -755,8 +752,6 @@ protected: bool mCurrentOpacity; std::atomic<uint64_t> mCurrentFrameNumber; bool mFrameLatencyNeeded; - // Whether filtering is forced on or not - bool mFiltering; // Whether filtering is needed b/c of the drawingstate bool mNeedsFiltering; diff --git a/services/surfaceflinger/RenderArea.cpp b/services/surfaceflinger/RenderArea.cpp index 1a8edf3e79..93759e8ad7 100644 --- a/services/surfaceflinger/RenderArea.cpp +++ b/services/surfaceflinger/RenderArea.cpp @@ -1,7 +1,5 @@ #include "RenderArea.h" -#include <gui/LayerState.h> - namespace android { float RenderArea::getCaptureFillValue(CaptureFill captureFill) { @@ -13,37 +11,5 @@ float RenderArea::getCaptureFillValue(CaptureFill captureFill) { return 1.0f; } } -/* - * Checks that the requested width and height are valid and updates them to the render area - * dimensions if they are set to 0 - */ -status_t RenderArea::updateDimensions(int displayRotation) { - // get screen geometry - - uint32_t width = getWidth(); - uint32_t height = getHeight(); - - if (mRotationFlags & Transform::ROT_90) { - std::swap(width, height); - } - - if (displayRotation & DisplayState::eOrientationSwapMask) { - std::swap(width, height); - } - - if ((mReqWidth > width) || (mReqHeight > height)) { - ALOGE("size mismatch (%d, %d) > (%d, %d)", mReqWidth, mReqHeight, width, height); - return BAD_VALUE; - } - - if (mReqWidth == 0) { - mReqWidth = width; - } - if (mReqHeight == 0) { - mReqHeight = height; - } - - return NO_ERROR; -} } // namespace android diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h index 96e4b5f48b..d980bd53c8 100644 --- a/services/surfaceflinger/RenderArea.h +++ b/services/surfaceflinger/RenderArea.h @@ -1,50 +1,80 @@ #pragma once -#include <ui/GraphicTypes.h> - #include "Transform.h" #include <functional> namespace android { +// RenderArea describes a rectangular area that layers can be rendered to. +// +// There is a logical render area and a physical render area. When a layer is +// rendered to the render area, it is first transformed and clipped to the logical +// render area. The transformed and clipped layer is then projected onto the +// physical render area. class RenderArea { - public: enum class CaptureFill {CLEAR, OPAQUE}; static float getCaptureFillValue(CaptureFill captureFill); - RenderArea(uint32_t reqHeight, uint32_t reqWidth, CaptureFill captureFill, - ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone) - : mReqHeight(reqHeight), mReqWidth(reqWidth), mCaptureFill(captureFill) { - mRotationFlags = Transform::fromRotation(rotation); - } + RenderArea(uint32_t reqWidth, uint32_t reqHeight, CaptureFill captureFill, + Transform::orientation_flags rotation = Transform::ROT_0) + : mReqWidth(reqWidth), + mReqHeight(reqHeight), + mCaptureFill(captureFill), + mRotationFlags(rotation) {} virtual ~RenderArea() = default; - virtual const Transform& getTransform() const = 0; - virtual Rect getBounds() const = 0; - virtual int getHeight() const = 0; - virtual int getWidth() const = 0; + // Invoke drawLayers to render layers into the render area. + virtual void render(std::function<void()> drawLayers) { drawLayers(); } + + // Returns true if the render area is secure. A secure layer should be + // blacked out / skipped when rendered to an insecure render area. virtual bool isSecure() const = 0; + + // Returns true if the otherwise disabled layer filtering should be + // enabled when rendering to this render area. virtual bool needsFiltering() const = 0; + + // Returns the transform to be applied on layers to transform them into + // the logical render area. + virtual const Transform& getTransform() const = 0; + + // Returns the size of the logical render area. Layers are clipped to the + // logical render area. + virtual int getWidth() const = 0; + virtual int getHeight() const = 0; + virtual Rect getBounds() const = 0; + + // Returns the source crop of the render area. The source crop defines + // how layers are projected from the logical render area onto the physical + // render area. It can be larger than the logical render area. It can + // also be optionally rotated. + // + // Layers are first clipped to the source crop (in addition to being + // clipped to the logical render area already). The source crop and the + // layers are then rotated around the center of the source crop, and + // scaled to the physical render area linearly. virtual Rect getSourceCrop() const = 0; - virtual void render(std::function<void()> drawLayers) { drawLayers(); } + // Returns the rotation of the source crop and the layers. + Transform::orientation_flags getRotationFlags() const { return mRotationFlags; }; - int getReqHeight() const { return mReqHeight; }; + // Returns the size of the physical render area. int getReqWidth() const { return mReqWidth; }; - Transform::orientation_flags getRotationFlags() const { return mRotationFlags; }; - status_t updateDimensions(int displayRotation); + int getReqHeight() const { return mReqHeight; }; + // Returns the fill color of the physical render area. Regions not + // covered by any rendered layer should be filled with this color. CaptureFill getCaptureFill() const { return mCaptureFill; }; private: - uint32_t mReqHeight; - uint32_t mReqWidth; - Transform::orientation_flags mRotationFlags; - CaptureFill mCaptureFill; + const uint32_t mReqWidth; + const uint32_t mReqHeight; + const CaptureFill mCaptureFill; + const Transform::orientation_flags mRotationFlags; }; } // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 4ec1e7f166..78d751a212 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -75,6 +75,7 @@ #include "LayerVector.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" +#include "Transform.h" #include "clz.h" #include "DisplayHardware/ComposerHal.h" @@ -112,6 +113,27 @@ using ui::Hdr; using ui::RenderIntent; namespace { + +#pragma clang diagnostic push +#pragma clang diagnostic error "-Wswitch-enum" + +Transform::orientation_flags fromSurfaceComposerRotation(ISurfaceComposer::Rotation rotation) { + switch (rotation) { + case ISurfaceComposer::eRotateNone: + return Transform::ROT_0; + case ISurfaceComposer::eRotate90: + return Transform::ROT_90; + case ISurfaceComposer::eRotate180: + return Transform::ROT_180; + case ISurfaceComposer::eRotate270: + return Transform::ROT_270; + } + ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation); + return Transform::ROT_0; +} + +#pragma clang diagnostic pop + class ConditionalLock { public: ConditionalLock(Mutex& mutex, bool lock) : mMutex(mutex), mLocked(lock) { @@ -144,7 +166,7 @@ bool SurfaceFlinger::useVrFlinger; int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers; // TODO(courtneygo): Rename hasWideColorDisplay to clarify its actual meaning. bool SurfaceFlinger::hasWideColorDisplay; - +int SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault; std::string getHwcServiceName() { char value[PROPERTY_VALUE_MAX] = {}; @@ -278,19 +300,19 @@ SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) { switch (primaryDisplayOrientation) { case V1_1::DisplayOrientation::ORIENTATION_90: - mPrimaryDisplayOrientation = DisplayState::eOrientation90; + SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation90; break; case V1_1::DisplayOrientation::ORIENTATION_180: - mPrimaryDisplayOrientation = DisplayState::eOrientation180; + SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation180; break; case V1_1::DisplayOrientation::ORIENTATION_270: - mPrimaryDisplayOrientation = DisplayState::eOrientation270; + SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation270; break; default: - mPrimaryDisplayOrientation = DisplayState::eOrientationDefault; + SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault; break; } - ALOGV("Primary Display Orientation is set to %2d.", mPrimaryDisplayOrientation); + ALOGV("Primary Display Orientation is set to %2d.", SurfaceFlinger::primaryDisplayOrientation); mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset); @@ -952,7 +974,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, info.secure = true; if (type == DisplayDevice::DISPLAY_PRIMARY && - mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) { + primaryDisplayOrientation & DisplayState::eOrientationSwapMask) { std::swap(info.w, info.h); } @@ -2395,6 +2417,9 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( nativeWindow->setSwapInterval(nativeWindow.get(), 0); } + const int displayInstallOrientation = state.type == DisplayDevice::DISPLAY_PRIMARY ? + primaryDisplayOrientation : DisplayState::eOrientationDefault; + // virtual displays are always considered enabled auto initialPowerMode = (state.type >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF; @@ -2402,7 +2427,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( sp<DisplayDevice> hw = new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow, dispSurface, std::move(renderSurface), displayWidth, displayHeight, - hasWideColorGamut, hdrCapabilities, + displayInstallOrientation, hasWideColorGamut, hdrCapabilities, supportedPerFrameMetadata, hwcColorModes, initialPowerMode); if (maxFrameBufferAcquiredBuffers >= 3) { @@ -4832,20 +4857,24 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, sp<GraphicBuf if (CC_UNLIKELY(display == 0)) return BAD_VALUE; - const sp<const DisplayDevice> device(getDisplayDeviceLocked(display)); - if (CC_UNLIKELY(device == 0)) return BAD_VALUE; + auto renderAreaRotation = fromSurfaceComposerRotation(rotation); - const Rect& dispScissor = device->getScissor(); - if (!dispScissor.isEmpty()) { - sourceCrop.set(dispScissor); - // adb shell screencap will default reqWidth and reqHeight to zeros. + sp<DisplayDevice> device; + { + Mutex::Autolock _l(mStateLock); + + device = getDisplayDeviceLocked(display); + if (!device) return BAD_VALUE; + + // set the requested width/height to the logical display viewport size + // by default if (reqWidth == 0 || reqHeight == 0) { reqWidth = uint32_t(device->getViewport().width()); reqHeight = uint32_t(device->getViewport().height()); } } - DisplayRenderArea renderArea(device, sourceCrop, reqHeight, reqWidth, rotation); + DisplayRenderArea renderArea(device, sourceCrop, reqWidth, reqHeight, renderAreaRotation); auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this, device, minLayerZ, maxLayerZ, std::placeholders::_1); @@ -4861,9 +4890,10 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, public: LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop, int32_t reqWidth, int32_t reqHeight, bool childrenOnly) - : RenderArea(reqHeight, reqWidth, CaptureFill::CLEAR), + : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR), mLayer(layer), mCrop(crop), + mNeedsFiltering(false), mFlinger(flinger), mChildrenOnly(childrenOnly) {} const Transform& getTransform() const override { return mTransform; } @@ -4874,7 +4904,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, int getHeight() const override { return mLayer->getDrawingState().active.h; } int getWidth() const override { return mLayer->getDrawingState().active.w; } bool isSecure() const override { return false; } - bool needsFiltering() const override { return false; } + bool needsFiltering() const override { return mNeedsFiltering; } Rect getSourceCrop() const override { if (mCrop.isEmpty()) { return getBounds(); @@ -4895,6 +4925,11 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, }; void render(std::function<void()> drawLayers) override { + const Rect sourceCrop = getSourceCrop(); + // no need to check rotation because there is none + mNeedsFiltering = sourceCrop.width() != getReqWidth() || + sourceCrop.height() != getReqHeight(); + if (!mChildrenOnly) { mTransform = mLayer->getTransform().inverse(); drawLayers(); @@ -4917,6 +4952,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, // layer which has no properties set and which does not draw. sp<ContainerLayer> screenshotParentLayer; Transform mTransform; + bool mNeedsFiltering; SurfaceFlinger* mFlinger; const bool mChildrenOnly; @@ -4951,6 +4987,14 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder, int32_t reqWidth = crop.width() * frameScale; int32_t reqHeight = crop.height() * frameScale; + // really small crop or frameScale + if (reqWidth <= 0) { + reqWidth = 1; + } + if (reqHeight <= 0) { + reqHeight = 1; + } + LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly); auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) { @@ -4972,8 +5016,6 @@ status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea, bool useIdentityTransform) { ATRACE_CALL(); - renderArea.updateDimensions(mPrimaryDisplayOrientation); - const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; *outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(), @@ -5049,57 +5091,12 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, auto& engine(getRenderEngine()); // get screen geometry - const auto raWidth = renderArea.getWidth(); const auto raHeight = renderArea.getHeight(); const auto reqWidth = renderArea.getReqWidth(); const auto reqHeight = renderArea.getReqHeight(); - Rect sourceCrop = renderArea.getSourceCrop(); - - bool filtering = false; - if (mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) { - filtering = static_cast<int32_t>(reqWidth) != raHeight || - static_cast<int32_t>(reqHeight) != raWidth; - } else { - filtering = static_cast<int32_t>(reqWidth) != raWidth || - static_cast<int32_t>(reqHeight) != raHeight; - } - - // if a default or invalid sourceCrop is passed in, set reasonable values - if (sourceCrop.width() == 0 || sourceCrop.height() == 0 || !sourceCrop.isValid()) { - sourceCrop.setLeftTop(Point(0, 0)); - sourceCrop.setRightBottom(Point(raWidth, raHeight)); - } else if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) { - Transform tr; - uint32_t flags = 0x00; - switch (mPrimaryDisplayOrientation) { - case DisplayState::eOrientation90: - flags = Transform::ROT_90; - break; - case DisplayState::eOrientation180: - flags = Transform::ROT_180; - break; - case DisplayState::eOrientation270: - flags = Transform::ROT_270; - break; - } - tr.set(flags, raWidth, raHeight); - sourceCrop = tr.transform(sourceCrop); - } - - // ensure that sourceCrop is inside screen - if (sourceCrop.left < 0) { - ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left); - } - if (sourceCrop.right > raWidth) { - ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, raWidth); - } - if (sourceCrop.top < 0) { - ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top); - } - if (sourceCrop.bottom > raHeight) { - ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, raHeight); - } + const auto sourceCrop = renderArea.getSourceCrop(); + const auto rotation = renderArea.getRotationFlags(); // assume ColorMode::SRGB / RenderIntent::COLORIMETRIC engine.setOutputDataSpace(Dataspace::SRGB); @@ -5108,37 +5105,6 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, // make sure to clear all GL error flags engine.checkErrors(); - Transform::orientation_flags rotation = renderArea.getRotationFlags(); - if (mPrimaryDisplayOrientation != DisplayState::eOrientationDefault) { - // convert hw orientation into flag presentation - // here inverse transform needed - uint8_t hw_rot_90 = 0x00; - uint8_t hw_flip_hv = 0x00; - switch (mPrimaryDisplayOrientation) { - case DisplayState::eOrientation90: - hw_rot_90 = Transform::ROT_90; - hw_flip_hv = Transform::ROT_180; - break; - case DisplayState::eOrientation180: - hw_flip_hv = Transform::ROT_180; - break; - case DisplayState::eOrientation270: - hw_rot_90 = Transform::ROT_90; - break; - } - - // transform flags operation - // 1) flip H V if both have ROT_90 flag - // 2) XOR these flags - uint8_t rotation_rot_90 = rotation & Transform::ROT_90; - uint8_t rotation_flip_hv = rotation & Transform::ROT_180; - if (rotation_rot_90 & hw_rot_90) { - rotation_flip_hv = (~rotation_flip_hv) & Transform::ROT_180; - } - rotation = static_cast<Transform::orientation_flags> - ((rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv)); - } - // set-up our viewport engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, raHeight, yswap, rotation); @@ -5149,9 +5115,7 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, engine.clearWithColor(0, 0, 0, alpha); traverseLayers([&](Layer* layer) { - if (filtering) layer->setFiltering(true); layer->draw(renderArea, useIdentityTransform); - if (filtering) layer->setFiltering(false); }); } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index d2b1233a5e..0914a097e4 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -286,6 +286,8 @@ public: // want to support color management to disable color management. static bool hasWideColorDisplay; + static int primaryDisplayOrientation; + static char const* getServiceName() ANDROID_API { return "SurfaceFlinger"; } @@ -345,8 +347,6 @@ public: bool authenticateSurfaceTextureLocked( const sp<IGraphicBufferProducer>& bufferProducer) const; - int getPrimaryDisplayOrientation() const { return mPrimaryDisplayOrientation; } - private: friend class Client; friend class DisplayEventConnection; @@ -858,7 +858,6 @@ private: mutable std::unique_ptr<MessageQueue> mEventQueue{std::make_unique<impl::MessageQueue>()}; FrameTracker mAnimFrameTracker; DispSync mPrimaryDispSync; - int mPrimaryDisplayOrientation = DisplayState::eOrientationDefault; // protected by mDestroyedLayerLock; mutable Mutex mDestroyedLayerLock; diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 558845f09b..4c5fa9953e 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -110,7 +110,7 @@ public: */ auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; } - + auto& mutablePrimaryDisplayOrientation() { return SurfaceFlinger::primaryDisplayOrientation; } auto& mutableBuiltinDisplays() { return mFlinger->mBuiltinDisplays; } auto& mutableCurrentState() { return mFlinger->mCurrentState; } auto& mutableDisplays() { return mFlinger->mDisplays; } @@ -320,10 +320,11 @@ public: sp<DisplayDevice> inject() { std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hdrAndRenderIntents; sp<DisplayDevice> device = - new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, mSecure, mDisplayToken, - mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0, - 0, false, HdrCapabilities(), 0, hdrAndRenderIntents, - HWC_POWER_MODE_NORMAL); + new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, mSecure, + mDisplayToken, mNativeWindow, mDisplaySurface, + std::move(mRenderSurface), 0, 0, + DisplayState::eOrientationDefault, false, HdrCapabilities(), + 0, hdrAndRenderIntents, HWC_POWER_MODE_NORMAL); mFlinger.mutableDisplays().add(mDisplayToken, device); DisplayDeviceState state(mType, mSecure); |