| /* | 
 |  * 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(bool useIdentityTransform, | 
 |                                                  const DisplayDevice& display) { | 
 |     if (!useIdentityTransform) { | 
 |         return RenderArea::RotationFlags::ROT_0; | 
 |     } | 
 |  | 
 |     return ui::Transform::toRotationFlags(display.getOrientation()); | 
 | } | 
 |  | 
 | } // namespace | 
 |  | 
 | std::unique_ptr<RenderArea> DisplayRenderArea::create(wp<const DisplayDevice> displayWeak, | 
 |                                                       const Rect& sourceCrop, ui::Size reqSize, | 
 |                                                       ui::Dataspace reqDataSpace, | 
 |                                                       bool useIdentityTransform, | 
 |                                                       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, | 
 |                                       useIdentityTransform, allowSecureLayers)); | 
 |     } | 
 |     return nullptr; | 
 | } | 
 |  | 
 | DisplayRenderArea::DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, | 
 |                                      ui::Size reqSize, ui::Dataspace reqDataSpace, | 
 |                                      bool useIdentityTransform, bool allowSecureLayers) | 
 |       : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, display->getLayerStackSpaceRect(), | 
 |                    allowSecureLayers, applyDeviceOrientation(useIdentityTransform, *display)), | 
 |         mDisplay(std::move(display)), | 
 |         mSourceCrop(sourceCrop) {} | 
 |  | 
 | 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->getLayerStackSpaceRect(); | 
 |     } | 
 |  | 
 |     // Correct for the orientation when the screen capture request contained | 
 |     // useIdentityTransform. This will cause the rotation flag to be non 0 since | 
 |     // it needs to rotate based on the screen orientation to allow the screenshot | 
 |     // to be taken in the ROT_0 orientation | 
 |     const auto flags = getRotationFlags(); | 
 |     int width = mDisplay->getLayerStackSpaceRect().getWidth(); | 
 |     int height = mDisplay->getLayerStackSpaceRect().getHeight(); | 
 |     ui::Transform rotation; | 
 |     rotation.set(flags, width, height); | 
 |     return rotation.transform(mSourceCrop); | 
 | } | 
 |  | 
 | } // namespace android |