| Marin Shalamanov | f6b5d18 | 2020-06-12 02:08:51 +0200 | [diff] [blame] | 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 |  | 
|  | 32 | 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 | } | 
|  | 40 | ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); } | 
|  | 41 | }; | 
|  | 42 |  | 
|  | 43 | } // namespace | 
|  | 44 |  | 
|  | 45 | LayerRenderArea::LayerRenderArea(SurfaceFlinger& flinger, sp<Layer> layer, const Rect& crop, | 
|  | 46 | ui::Size reqSize, ui::Dataspace reqDataSpace, bool childrenOnly, | 
| Marin Shalamanov | 6ad317c | 2020-07-29 23:34:07 +0200 | [diff] [blame] | 47 | const Rect& layerStackRect, bool allowSecureLayers) | 
|  | 48 | : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, layerStackRect, allowSecureLayers), | 
| Marin Shalamanov | f6b5d18 | 2020-06-12 02:08:51 +0200 | [diff] [blame] | 49 | mLayer(std::move(layer)), | 
|  | 50 | mCrop(crop), | 
|  | 51 | mFlinger(flinger), | 
|  | 52 | mChildrenOnly(childrenOnly) {} | 
|  | 53 |  | 
|  | 54 | const ui::Transform& LayerRenderArea::getTransform() const { | 
|  | 55 | return mTransform; | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | Rect LayerRenderArea::getBounds() const { | 
|  | 59 | return mLayer->getBufferSize(mLayer->getDrawingState()); | 
|  | 60 | } | 
|  | 61 |  | 
|  | 62 | int LayerRenderArea::getHeight() const { | 
|  | 63 | return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight(); | 
|  | 64 | } | 
|  | 65 |  | 
|  | 66 | int LayerRenderArea::getWidth() const { | 
|  | 67 | return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth(); | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | bool LayerRenderArea::isSecure() const { | 
| chaviw | 70cb6a4 | 2020-07-30 13:57:36 -0700 | [diff] [blame] | 71 | return mAllowSecureLayers; | 
| Marin Shalamanov | f6b5d18 | 2020-06-12 02:08:51 +0200 | [diff] [blame] | 72 | } | 
|  | 73 |  | 
|  | 74 | bool LayerRenderArea::needsFiltering() const { | 
|  | 75 | return mNeedsFiltering; | 
|  | 76 | } | 
|  | 77 |  | 
|  | 78 | sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const { | 
|  | 79 | return nullptr; | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | Rect LayerRenderArea::getSourceCrop() const { | 
|  | 83 | if (mCrop.isEmpty()) { | 
|  | 84 | return getBounds(); | 
|  | 85 | } else { | 
|  | 86 | return mCrop; | 
|  | 87 | } | 
|  | 88 | } | 
|  | 89 |  | 
|  | 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 |  | 
| chaviw | 79468ab | 2021-10-27 11:11:24 -0500 | [diff] [blame] | 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 |  | 
| Marin Shalamanov | f6b5d18 | 2020-06-12 02:08:51 +0200 | [diff] [blame] | 105 | if (!mChildrenOnly) { | 
|  | 106 | mTransform = mLayer->getTransform().inverse(); | 
| chaviw | 79468ab | 2021-10-27 11:11:24 -0500 | [diff] [blame] | 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 | } | 
| Marin Shalamanov | f6b5d18 | 2020-06-12 02:08:51 +0200 | [diff] [blame] | 113 | drawLayers(); | 
|  | 114 | } else { | 
| Marin Shalamanov | f6b5d18 | 2020-06-12 02:08:51 +0200 | [diff] [blame] | 115 | // In the "childrenOnly" case we reparent the children to a screenshot | 
|  | 116 | // layer which has no properties set and which does not draw. | 
|  | 117 | sp<ContainerLayer> screenshotParentLayer = mFlinger.getFactory().createContainerLayer( | 
| Vishnu Nair | 7fb9e5a | 2021-11-08 12:44:05 -0800 | [diff] [blame] | 118 | {&mFlinger, nullptr, "Screenshot Parent"s, 0, LayerMetadata()}); | 
| Marin Shalamanov | f6b5d18 | 2020-06-12 02:08:51 +0200 | [diff] [blame] | 119 |  | 
|  | 120 | ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop); | 
|  | 121 | drawLayers(); | 
|  | 122 | } | 
|  | 123 | } | 
|  | 124 |  | 
|  | 125 | } // namespace android |