diff options
Diffstat (limited to 'services/surfaceflinger/LayerRenderArea.cpp')
-rw-r--r-- | services/surfaceflinger/LayerRenderArea.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp new file mode 100644 index 0000000000..e84508febc --- /dev/null +++ b/services/surfaceflinger/LayerRenderArea.cpp @@ -0,0 +1,113 @@ +/* + * 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& layerStackRect, bool allowSecureLayers) + : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, layerStackRect, allowSecureLayers), + 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 mAllowSecureLayers; +} + +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 |