1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <ui/GraphicTypes.h>
18 #include <ui/Transform.h>
19 
20 #include "ContainerLayer.h"
21 #include "DisplayDevice.h"
22 #include "Layer.h"
23 #include "LayerRenderArea.h"
24 #include "SurfaceFlinger.h"
25 
26 namespace android {
27 namespace {
28 
29 struct ReparentForDrawing {
30     const sp<Layer>& oldParent;
31 
ReparentForDrawingandroid::__anon13df28aa0110::ReparentForDrawing32     ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent,
33                        const Rect& drawingBounds)
34           : oldParent(oldParent) {
35         // Compute and cache the bounds for the new parent layer.
36         newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(),
37                                  0.f /* shadowRadius */);
38         oldParent->setChildrenDrawingParent(newParent);
39     }
~ReparentForDrawingandroid::__anon13df28aa0110::ReparentForDrawing40     ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); }
41 };
42 
43 } // namespace
44 
LayerRenderArea(SurfaceFlinger & flinger,sp<Layer> layer,const Rect & crop,ui::Size reqSize,ui::Dataspace reqDataSpace,bool childrenOnly,const Rect & layerStackRect,bool allowSecureLayers)45 LayerRenderArea::LayerRenderArea(SurfaceFlinger& flinger, sp<Layer> layer, const Rect& crop,
46                                  ui::Size reqSize, ui::Dataspace reqDataSpace, bool childrenOnly,
47                                  const Rect& layerStackRect, bool allowSecureLayers)
48       : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, layerStackRect, allowSecureLayers),
49         mLayer(std::move(layer)),
50         mCrop(crop),
51         mFlinger(flinger),
52         mChildrenOnly(childrenOnly) {}
53 
getTransform() const54 const ui::Transform& LayerRenderArea::getTransform() const {
55     return mTransform;
56 }
57 
getBounds() const58 Rect LayerRenderArea::getBounds() const {
59     return mLayer->getBufferSize(mLayer->getDrawingState());
60 }
61 
getHeight() const62 int LayerRenderArea::getHeight() const {
63     return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight();
64 }
65 
getWidth() const66 int LayerRenderArea::getWidth() const {
67     return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth();
68 }
69 
isSecure() const70 bool LayerRenderArea::isSecure() const {
71     return mAllowSecureLayers;
72 }
73 
needsFiltering() const74 bool LayerRenderArea::needsFiltering() const {
75     return mNeedsFiltering;
76 }
77 
getDisplayDevice() const78 sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const {
79     return nullptr;
80 }
81 
getSourceCrop() const82 Rect LayerRenderArea::getSourceCrop() const {
83     if (mCrop.isEmpty()) {
84         return getBounds();
85     } else {
86         return mCrop;
87     }
88 }
89 
render(std::function<void ()> drawLayers)90 void LayerRenderArea::render(std::function<void()> drawLayers) {
91     using namespace std::string_literals;
92 
93     const Rect sourceCrop = getSourceCrop();
94     // no need to check rotation because there is none
95     mNeedsFiltering = sourceCrop.width() != getReqWidth() || sourceCrop.height() != getReqHeight();
96 
97     // If layer is offscreen, update mirroring info if it exists
98     if (mLayer->isRemovedFromCurrentState()) {
99         mLayer->traverse(LayerVector::StateSet::Drawing,
100                          [&](Layer* layer) { layer->updateMirrorInfo(); });
101         mLayer->traverse(LayerVector::StateSet::Drawing,
102                          [&](Layer* layer) { layer->updateCloneBufferInfo(); });
103     }
104 
105     if (!mChildrenOnly) {
106         mTransform = mLayer->getTransform().inverse();
107         // If the layer is offscreen, compute bounds since we don't compute bounds for offscreen
108         // layers in a regular cycles.
109         if (mLayer->isRemovedFromCurrentState()) {
110             FloatRect maxBounds = mFlinger.getMaxDisplayBounds();
111             mLayer->computeBounds(maxBounds, ui::Transform(), 0.f /* shadowRadius */);
112         }
113         drawLayers();
114     } else {
115         uint32_t w = static_cast<uint32_t>(getWidth());
116         uint32_t h = static_cast<uint32_t>(getHeight());
117         // In the "childrenOnly" case we reparent the children to a screenshot
118         // layer which has no properties set and which does not draw.
119         sp<ContainerLayer> screenshotParentLayer = mFlinger.getFactory().createContainerLayer(
120                 {&mFlinger, nullptr, "Screenshot Parent"s, w, h, 0, LayerMetadata()});
121 
122         ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop);
123         drawLayers();
124     }
125 }
126 
127 } // namespace android
128