/* * 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 #include #include "ContainerLayer.h" #include "DisplayDevice.h" #include "Layer.h" #include "LayerRenderArea.h" #include "SurfaceFlinger.h" namespace android { namespace { void reparentForDrawing(const sp& oldParent, const sp& newParent, const Rect& drawingBounds) { // Compute and cache the bounds for the new parent layer. newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(), 0.f /* shadowRadius */); oldParent->setChildrenDrawingParent(newParent); }; } // namespace LayerRenderArea::LayerRenderArea(SurfaceFlinger& flinger, sp 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 LayerRenderArea::getDisplayDevice() const { return nullptr; } Rect LayerRenderArea::getSourceCrop() const { if (mCrop.isEmpty()) { return getBounds(); } else { return mCrop; } } void LayerRenderArea::render(std::function 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(getWidth()); uint32_t h = static_cast(getHeight()); // In the "childrenOnly" case we reparent the children to a screenshot // layer which has no properties set and which does not draw. sp screenshotParentLayer = mFlinger.getFactory().createContainerLayer( {&mFlinger, nullptr, "Screenshot Parent"s, w, h, 0, LayerMetadata()}); { Mutex::Autolock _l(mFlinger.mStateLock); reparentForDrawing(mLayer, screenshotParentLayer, sourceCrop); } drawLayers(); { Mutex::Autolock _l(mFlinger.mStateLock); mLayer->setChildrenDrawingParent(mLayer); } } } } // namespace android