Loading services/surfaceflinger/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,7 @@ filegroup { "DisplayHardware/HWComposer.cpp", "DisplayHardware/PowerAdvisor.cpp", "DisplayHardware/VirtualDisplaySurface.cpp", "DisplayRenderArea.cpp", "Effects/Daltonizer.cpp", "EventLog/EventLog.cpp", "FrameTracer/FrameTracer.cpp", Loading @@ -152,6 +153,7 @@ filegroup { "Layer.cpp", "LayerProtoHelper.cpp", "LayerRejecter.cpp", "LayerRenderArea.cpp", "LayerVector.cpp", "MonitoredProducer.cpp", "NativeWindowSurface.cpp", Loading services/surfaceflinger/DisplayDevice.h +0 −120 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ #include "DisplayHardware/DisplayIdentification.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/PowerAdvisor.h" #include "RenderArea.h" #include "Scheduler/HwcStrongTypes.h" namespace android { Loading Loading @@ -246,123 +245,4 @@ struct DisplayDeviceCreationArgs { bool isPrimary{false}; }; class DisplayRenderArea : public RenderArea { public: static std::unique_ptr<RenderArea> create(wp<const DisplayDevice> displayWeak, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers = true) { if (auto display = displayWeak.promote()) { // Using new to access a private constructor. return std::unique_ptr<DisplayRenderArea>( new DisplayRenderArea(std::move(display), sourceCrop, reqSize, reqDataSpace, rotation, allowSecureLayers)); } return nullptr; } const ui::Transform& getTransform() const override { return mTransform; } Rect getBounds() const override { return mDisplay->getBounds(); } int getHeight() const override { return mDisplay->getHeight(); } int getWidth() const override { return mDisplay->getWidth(); } bool isSecure() const override { return mAllowSecureLayers && mDisplay->isSecure(); } sp<const DisplayDevice> getDisplayDevice() const override { return mDisplay; } bool needsFiltering() const override { // check if the projection from the logical render area // to the physical render area requires filtering const Rect& sourceCrop = getSourceCrop(); int width = sourceCrop.width(); int height = sourceCrop.height(); if (getRotationFlags() & ui::Transform::ROT_90) { std::swap(width, height); } return width != getReqWidth() || height != getReqHeight(); } Rect getSourceCrop() const override { // use the projected display viewport by default. if (mSourceCrop.isEmpty()) { return mDisplay->getSourceClip(); } // If there is a source crop provided then it is assumed that the device // was in portrait orientation. This may not logically be true, so // correct for the orientation error by undoing the rotation ui::Rotation logicalOrientation = mDisplay->getOrientation(); if (logicalOrientation == ui::Rotation::Rotation90) { logicalOrientation = ui::Rotation::Rotation270; } else if (logicalOrientation == ui::Rotation::Rotation270) { logicalOrientation = ui::Rotation::Rotation90; } const auto flags = ui::Transform::toRotationFlags(logicalOrientation); int width = mDisplay->getSourceClip().getWidth(); int height = mDisplay->getSourceClip().getHeight(); ui::Transform rotation; rotation.set(flags, width, height); return rotation.transform(mSourceCrop); } private: DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers) : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, display->getViewport(), applyDeviceOrientation(rotation, display)), mDisplay(std::move(display)), mSourceCrop(sourceCrop), mAllowSecureLayers(allowSecureLayers) {} static RotationFlags applyDeviceOrientation(RotationFlags orientationFlag, const sp<const DisplayDevice>& device) { uint32_t inverseRotate90 = 0; uint32_t inverseReflect = 0; // Reverse the logical orientation. ui::Rotation logicalOrientation = device->getOrientation(); if (logicalOrientation == ui::Rotation::Rotation90) { logicalOrientation = ui::Rotation::Rotation270; } else if (logicalOrientation == ui::Rotation::Rotation270) { logicalOrientation = ui::Rotation::Rotation90; } const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation; switch (orientation) { case ui::ROTATION_0: return orientationFlag; case ui::ROTATION_90: inverseRotate90 = ui::Transform::ROT_90; inverseReflect = ui::Transform::ROT_180; break; case ui::ROTATION_180: inverseReflect = ui::Transform::ROT_180; break; case ui::ROTATION_270: inverseRotate90 = ui::Transform::ROT_90; break; } const uint32_t rotate90 = orientationFlag & ui::Transform::ROT_90; uint32_t reflect = orientationFlag & ui::Transform::ROT_180; // Apply reflection for double rotation. if (rotate90 & inverseRotate90) { reflect = ~reflect & ui::Transform::ROT_180; } return static_cast<RotationFlags>((rotate90 ^ inverseRotate90) | (reflect ^ inverseReflect)); } const sp<const DisplayDevice> mDisplay; const Rect mSourceCrop; const bool mAllowSecureLayers; const ui::Transform mTransform = ui::Transform(); }; } // namespace android services/surfaceflinger/DisplayRenderArea.cpp 0 → 100644 +154 −0 Original line number Diff line number Diff line /* * Copyright 2020 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. */ #include "DisplayRenderArea.h" #include "DisplayDevice.h" namespace android { namespace { RenderArea::RotationFlags applyDeviceOrientation(RenderArea::RotationFlags rotation, const DisplayDevice& display) { uint32_t inverseRotate90 = 0; uint32_t inverseReflect = 0; // Reverse the logical orientation. ui::Rotation logicalOrientation = display.getOrientation(); if (logicalOrientation == ui::Rotation::Rotation90) { logicalOrientation = ui::Rotation::Rotation270; } else if (logicalOrientation == ui::Rotation::Rotation270) { logicalOrientation = ui::Rotation::Rotation90; } const ui::Rotation orientation = display.getPhysicalOrientation() + logicalOrientation; switch (orientation) { case ui::ROTATION_0: return rotation; case ui::ROTATION_90: inverseRotate90 = ui::Transform::ROT_90; inverseReflect = ui::Transform::ROT_180; break; case ui::ROTATION_180: inverseReflect = ui::Transform::ROT_180; break; case ui::ROTATION_270: inverseRotate90 = ui::Transform::ROT_90; break; } const uint32_t rotate90 = rotation & ui::Transform::ROT_90; uint32_t reflect = rotation & ui::Transform::ROT_180; // Apply reflection for double rotation. if (rotate90 & inverseRotate90) { reflect = ~reflect & ui::Transform::ROT_180; } return static_cast<RenderArea::RotationFlags>((rotate90 ^ inverseRotate90) | (reflect ^ inverseReflect)); } } // namespace std::unique_ptr<RenderArea> DisplayRenderArea::create(wp<const DisplayDevice> displayWeak, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers) { if (auto display = displayWeak.promote()) { // Using new to access a private constructor. return std::unique_ptr<DisplayRenderArea>( new DisplayRenderArea(std::move(display), sourceCrop, reqSize, reqDataSpace, rotation, allowSecureLayers)); } return nullptr; } DisplayRenderArea::DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers) : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, display->getViewport(), applyDeviceOrientation(rotation, *display)), mDisplay(std::move(display)), mSourceCrop(sourceCrop), mAllowSecureLayers(allowSecureLayers) {} const ui::Transform& DisplayRenderArea::getTransform() const { return mTransform; } Rect DisplayRenderArea::getBounds() const { return mDisplay->getBounds(); } int DisplayRenderArea::getHeight() const { return mDisplay->getHeight(); } int DisplayRenderArea::getWidth() const { return mDisplay->getWidth(); } bool DisplayRenderArea::isSecure() const { return mAllowSecureLayers && mDisplay->isSecure(); } sp<const DisplayDevice> DisplayRenderArea::getDisplayDevice() const { return mDisplay; } bool DisplayRenderArea::needsFiltering() const { // check if the projection from the logical render area // to the physical render area requires filtering const Rect& sourceCrop = getSourceCrop(); int width = sourceCrop.width(); int height = sourceCrop.height(); if (getRotationFlags() & ui::Transform::ROT_90) { std::swap(width, height); } return width != getReqWidth() || height != getReqHeight(); } Rect DisplayRenderArea::getSourceCrop() const { // use the projected display viewport by default. if (mSourceCrop.isEmpty()) { return mDisplay->getSourceClip(); } // If there is a source crop provided then it is assumed that the device // was in portrait orientation. This may not logically be true, so // correct for the orientation error by undoing the rotation ui::Rotation logicalOrientation = mDisplay->getOrientation(); if (logicalOrientation == ui::Rotation::Rotation90) { logicalOrientation = ui::Rotation::Rotation270; } else if (logicalOrientation == ui::Rotation::Rotation270) { logicalOrientation = ui::Rotation::Rotation90; } const auto flags = ui::Transform::toRotationFlags(logicalOrientation); int width = mDisplay->getSourceClip().getWidth(); int height = mDisplay->getSourceClip().getHeight(); ui::Transform rotation; rotation.set(flags, width, height); return rotation.transform(mSourceCrop); } } // namespace android No newline at end of file services/surfaceflinger/DisplayRenderArea.h 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright 2020 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 <ui/GraphicTypes.h> #include <ui/Transform.h> #include "RenderArea.h" namespace android { class DisplayDevice; class DisplayRenderArea : public RenderArea { public: static std::unique_ptr<RenderArea> create(wp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace, RotationFlags rotation, bool allowSecureLayers = true); const ui::Transform& getTransform() const override; Rect getBounds() const override; int getHeight() const override; int getWidth() const override; bool isSecure() const override; sp<const DisplayDevice> getDisplayDevice() const override; bool needsFiltering() const override; Rect getSourceCrop() const override; private: DisplayRenderArea(sp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace, RotationFlags rotation, bool allowSecureLayers = true); const sp<const DisplayDevice> mDisplay; const Rect mSourceCrop; const bool mAllowSecureLayers; const ui::Transform mTransform; }; } // namespace android No newline at end of file services/surfaceflinger/LayerRenderArea.cpp 0 → 100644 +113 −0 Original line number Diff line number Diff line /* * Copyright 2020 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. */ #include <ui/GraphicTypes.h> #include <ui/Transform.h> #include "ContainerLayer.h" #include "DisplayDevice.h" #include "Layer.h" #include "LayerRenderArea.h" #include "SurfaceFlinger.h" namespace android { namespace { struct ReparentForDrawing { const sp<Layer>& oldParent; ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent, const Rect& drawingBounds) : oldParent(oldParent) { // Compute and cache the bounds for the new parent layer. newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(), 0.f /* shadowRadius */); oldParent->setChildrenDrawingParent(newParent); } ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); } }; } // namespace LayerRenderArea::LayerRenderArea(SurfaceFlinger& flinger, sp<Layer> layer, const Rect& crop, ui::Size reqSize, ui::Dataspace reqDataSpace, bool childrenOnly, const Rect& displayViewport) : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, displayViewport), mLayer(std::move(layer)), mCrop(crop), mFlinger(flinger), mChildrenOnly(childrenOnly) {} const ui::Transform& LayerRenderArea::getTransform() const { return mTransform; } Rect LayerRenderArea::getBounds() const { return mLayer->getBufferSize(mLayer->getDrawingState()); } int LayerRenderArea::getHeight() const { return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight(); } int LayerRenderArea::getWidth() const { return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth(); } bool LayerRenderArea::isSecure() const { return false; } bool LayerRenderArea::needsFiltering() const { return mNeedsFiltering; } sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const { return nullptr; } Rect LayerRenderArea::getSourceCrop() const { if (mCrop.isEmpty()) { return getBounds(); } else { return mCrop; } } void LayerRenderArea::render(std::function<void()> drawLayers) { using namespace std::string_literals; 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(); } else { uint32_t w = static_cast<uint32_t>(getWidth()); uint32_t h = static_cast<uint32_t>(getHeight()); // In the "childrenOnly" case we reparent the children to a screenshot // layer which has no properties set and which does not draw. sp<ContainerLayer> screenshotParentLayer = mFlinger.getFactory().createContainerLayer( {&mFlinger, nullptr, "Screenshot Parent"s, w, h, 0, LayerMetadata()}); ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop); drawLayers(); } } } // namespace android Loading
services/surfaceflinger/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,7 @@ filegroup { "DisplayHardware/HWComposer.cpp", "DisplayHardware/PowerAdvisor.cpp", "DisplayHardware/VirtualDisplaySurface.cpp", "DisplayRenderArea.cpp", "Effects/Daltonizer.cpp", "EventLog/EventLog.cpp", "FrameTracer/FrameTracer.cpp", Loading @@ -152,6 +153,7 @@ filegroup { "Layer.cpp", "LayerProtoHelper.cpp", "LayerRejecter.cpp", "LayerRenderArea.cpp", "LayerVector.cpp", "MonitoredProducer.cpp", "NativeWindowSurface.cpp", Loading
services/surfaceflinger/DisplayDevice.h +0 −120 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ #include "DisplayHardware/DisplayIdentification.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/PowerAdvisor.h" #include "RenderArea.h" #include "Scheduler/HwcStrongTypes.h" namespace android { Loading Loading @@ -246,123 +245,4 @@ struct DisplayDeviceCreationArgs { bool isPrimary{false}; }; class DisplayRenderArea : public RenderArea { public: static std::unique_ptr<RenderArea> create(wp<const DisplayDevice> displayWeak, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers = true) { if (auto display = displayWeak.promote()) { // Using new to access a private constructor. return std::unique_ptr<DisplayRenderArea>( new DisplayRenderArea(std::move(display), sourceCrop, reqSize, reqDataSpace, rotation, allowSecureLayers)); } return nullptr; } const ui::Transform& getTransform() const override { return mTransform; } Rect getBounds() const override { return mDisplay->getBounds(); } int getHeight() const override { return mDisplay->getHeight(); } int getWidth() const override { return mDisplay->getWidth(); } bool isSecure() const override { return mAllowSecureLayers && mDisplay->isSecure(); } sp<const DisplayDevice> getDisplayDevice() const override { return mDisplay; } bool needsFiltering() const override { // check if the projection from the logical render area // to the physical render area requires filtering const Rect& sourceCrop = getSourceCrop(); int width = sourceCrop.width(); int height = sourceCrop.height(); if (getRotationFlags() & ui::Transform::ROT_90) { std::swap(width, height); } return width != getReqWidth() || height != getReqHeight(); } Rect getSourceCrop() const override { // use the projected display viewport by default. if (mSourceCrop.isEmpty()) { return mDisplay->getSourceClip(); } // If there is a source crop provided then it is assumed that the device // was in portrait orientation. This may not logically be true, so // correct for the orientation error by undoing the rotation ui::Rotation logicalOrientation = mDisplay->getOrientation(); if (logicalOrientation == ui::Rotation::Rotation90) { logicalOrientation = ui::Rotation::Rotation270; } else if (logicalOrientation == ui::Rotation::Rotation270) { logicalOrientation = ui::Rotation::Rotation90; } const auto flags = ui::Transform::toRotationFlags(logicalOrientation); int width = mDisplay->getSourceClip().getWidth(); int height = mDisplay->getSourceClip().getHeight(); ui::Transform rotation; rotation.set(flags, width, height); return rotation.transform(mSourceCrop); } private: DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers) : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, display->getViewport(), applyDeviceOrientation(rotation, display)), mDisplay(std::move(display)), mSourceCrop(sourceCrop), mAllowSecureLayers(allowSecureLayers) {} static RotationFlags applyDeviceOrientation(RotationFlags orientationFlag, const sp<const DisplayDevice>& device) { uint32_t inverseRotate90 = 0; uint32_t inverseReflect = 0; // Reverse the logical orientation. ui::Rotation logicalOrientation = device->getOrientation(); if (logicalOrientation == ui::Rotation::Rotation90) { logicalOrientation = ui::Rotation::Rotation270; } else if (logicalOrientation == ui::Rotation::Rotation270) { logicalOrientation = ui::Rotation::Rotation90; } const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation; switch (orientation) { case ui::ROTATION_0: return orientationFlag; case ui::ROTATION_90: inverseRotate90 = ui::Transform::ROT_90; inverseReflect = ui::Transform::ROT_180; break; case ui::ROTATION_180: inverseReflect = ui::Transform::ROT_180; break; case ui::ROTATION_270: inverseRotate90 = ui::Transform::ROT_90; break; } const uint32_t rotate90 = orientationFlag & ui::Transform::ROT_90; uint32_t reflect = orientationFlag & ui::Transform::ROT_180; // Apply reflection for double rotation. if (rotate90 & inverseRotate90) { reflect = ~reflect & ui::Transform::ROT_180; } return static_cast<RotationFlags>((rotate90 ^ inverseRotate90) | (reflect ^ inverseReflect)); } const sp<const DisplayDevice> mDisplay; const Rect mSourceCrop; const bool mAllowSecureLayers; const ui::Transform mTransform = ui::Transform(); }; } // namespace android
services/surfaceflinger/DisplayRenderArea.cpp 0 → 100644 +154 −0 Original line number Diff line number Diff line /* * Copyright 2020 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. */ #include "DisplayRenderArea.h" #include "DisplayDevice.h" namespace android { namespace { RenderArea::RotationFlags applyDeviceOrientation(RenderArea::RotationFlags rotation, const DisplayDevice& display) { uint32_t inverseRotate90 = 0; uint32_t inverseReflect = 0; // Reverse the logical orientation. ui::Rotation logicalOrientation = display.getOrientation(); if (logicalOrientation == ui::Rotation::Rotation90) { logicalOrientation = ui::Rotation::Rotation270; } else if (logicalOrientation == ui::Rotation::Rotation270) { logicalOrientation = ui::Rotation::Rotation90; } const ui::Rotation orientation = display.getPhysicalOrientation() + logicalOrientation; switch (orientation) { case ui::ROTATION_0: return rotation; case ui::ROTATION_90: inverseRotate90 = ui::Transform::ROT_90; inverseReflect = ui::Transform::ROT_180; break; case ui::ROTATION_180: inverseReflect = ui::Transform::ROT_180; break; case ui::ROTATION_270: inverseRotate90 = ui::Transform::ROT_90; break; } const uint32_t rotate90 = rotation & ui::Transform::ROT_90; uint32_t reflect = rotation & ui::Transform::ROT_180; // Apply reflection for double rotation. if (rotate90 & inverseRotate90) { reflect = ~reflect & ui::Transform::ROT_180; } return static_cast<RenderArea::RotationFlags>((rotate90 ^ inverseRotate90) | (reflect ^ inverseReflect)); } } // namespace std::unique_ptr<RenderArea> DisplayRenderArea::create(wp<const DisplayDevice> displayWeak, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers) { if (auto display = displayWeak.promote()) { // Using new to access a private constructor. return std::unique_ptr<DisplayRenderArea>( new DisplayRenderArea(std::move(display), sourceCrop, reqSize, reqDataSpace, rotation, allowSecureLayers)); } return nullptr; } DisplayRenderArea::DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers) : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, display->getViewport(), applyDeviceOrientation(rotation, *display)), mDisplay(std::move(display)), mSourceCrop(sourceCrop), mAllowSecureLayers(allowSecureLayers) {} const ui::Transform& DisplayRenderArea::getTransform() const { return mTransform; } Rect DisplayRenderArea::getBounds() const { return mDisplay->getBounds(); } int DisplayRenderArea::getHeight() const { return mDisplay->getHeight(); } int DisplayRenderArea::getWidth() const { return mDisplay->getWidth(); } bool DisplayRenderArea::isSecure() const { return mAllowSecureLayers && mDisplay->isSecure(); } sp<const DisplayDevice> DisplayRenderArea::getDisplayDevice() const { return mDisplay; } bool DisplayRenderArea::needsFiltering() const { // check if the projection from the logical render area // to the physical render area requires filtering const Rect& sourceCrop = getSourceCrop(); int width = sourceCrop.width(); int height = sourceCrop.height(); if (getRotationFlags() & ui::Transform::ROT_90) { std::swap(width, height); } return width != getReqWidth() || height != getReqHeight(); } Rect DisplayRenderArea::getSourceCrop() const { // use the projected display viewport by default. if (mSourceCrop.isEmpty()) { return mDisplay->getSourceClip(); } // If there is a source crop provided then it is assumed that the device // was in portrait orientation. This may not logically be true, so // correct for the orientation error by undoing the rotation ui::Rotation logicalOrientation = mDisplay->getOrientation(); if (logicalOrientation == ui::Rotation::Rotation90) { logicalOrientation = ui::Rotation::Rotation270; } else if (logicalOrientation == ui::Rotation::Rotation270) { logicalOrientation = ui::Rotation::Rotation90; } const auto flags = ui::Transform::toRotationFlags(logicalOrientation); int width = mDisplay->getSourceClip().getWidth(); int height = mDisplay->getSourceClip().getHeight(); ui::Transform rotation; rotation.set(flags, width, height); return rotation.transform(mSourceCrop); } } // namespace android No newline at end of file
services/surfaceflinger/DisplayRenderArea.h 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright 2020 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 <ui/GraphicTypes.h> #include <ui/Transform.h> #include "RenderArea.h" namespace android { class DisplayDevice; class DisplayRenderArea : public RenderArea { public: static std::unique_ptr<RenderArea> create(wp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace, RotationFlags rotation, bool allowSecureLayers = true); const ui::Transform& getTransform() const override; Rect getBounds() const override; int getHeight() const override; int getWidth() const override; bool isSecure() const override; sp<const DisplayDevice> getDisplayDevice() const override; bool needsFiltering() const override; Rect getSourceCrop() const override; private: DisplayRenderArea(sp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize, ui::Dataspace, RotationFlags rotation, bool allowSecureLayers = true); const sp<const DisplayDevice> mDisplay; const Rect mSourceCrop; const bool mAllowSecureLayers; const ui::Transform mTransform; }; } // namespace android No newline at end of file
services/surfaceflinger/LayerRenderArea.cpp 0 → 100644 +113 −0 Original line number Diff line number Diff line /* * Copyright 2020 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. */ #include <ui/GraphicTypes.h> #include <ui/Transform.h> #include "ContainerLayer.h" #include "DisplayDevice.h" #include "Layer.h" #include "LayerRenderArea.h" #include "SurfaceFlinger.h" namespace android { namespace { struct ReparentForDrawing { const sp<Layer>& oldParent; ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent, const Rect& drawingBounds) : oldParent(oldParent) { // Compute and cache the bounds for the new parent layer. newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(), 0.f /* shadowRadius */); oldParent->setChildrenDrawingParent(newParent); } ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); } }; } // namespace LayerRenderArea::LayerRenderArea(SurfaceFlinger& flinger, sp<Layer> layer, const Rect& crop, ui::Size reqSize, ui::Dataspace reqDataSpace, bool childrenOnly, const Rect& displayViewport) : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, displayViewport), mLayer(std::move(layer)), mCrop(crop), mFlinger(flinger), mChildrenOnly(childrenOnly) {} const ui::Transform& LayerRenderArea::getTransform() const { return mTransform; } Rect LayerRenderArea::getBounds() const { return mLayer->getBufferSize(mLayer->getDrawingState()); } int LayerRenderArea::getHeight() const { return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight(); } int LayerRenderArea::getWidth() const { return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth(); } bool LayerRenderArea::isSecure() const { return false; } bool LayerRenderArea::needsFiltering() const { return mNeedsFiltering; } sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const { return nullptr; } Rect LayerRenderArea::getSourceCrop() const { if (mCrop.isEmpty()) { return getBounds(); } else { return mCrop; } } void LayerRenderArea::render(std::function<void()> drawLayers) { using namespace std::string_literals; 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(); } else { uint32_t w = static_cast<uint32_t>(getWidth()); uint32_t h = static_cast<uint32_t>(getHeight()); // In the "childrenOnly" case we reparent the children to a screenshot // layer which has no properties set and which does not draw. sp<ContainerLayer> screenshotParentLayer = mFlinger.getFactory().createContainerLayer( {&mFlinger, nullptr, "Screenshot Parent"s, w, h, 0, LayerMetadata()}); ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop); drawLayers(); } } } // namespace android