/* * Copyright 2022 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 "ScreenCaptureOutput.h" #include "ScreenCaptureRenderSurface.h" #include #include #include #include namespace android { std::shared_ptr createScreenCaptureOutput(ScreenCaptureOutputArgs&& args) { std::shared_ptr output = compositionengine::impl::createOutputTemplated< ScreenCaptureOutput, compositionengine::CompositionEngine, ScreenCaptureOutputArgs&&>(args.compositionEngine, std::move(args)); output->editState().isSecure = args.renderArea.isSecure(); output->setCompositionEnabled(true); output->setLayerFilter({args.layerStack}); output->setRenderSurface(std::make_unique(std::move(args.buffer))); output->setDisplayBrightness(args.sdrWhitePointNits, args.displayBrightnessNits); output->setDisplayColorProfile(std::make_unique( compositionengine::DisplayColorProfileCreationArgsBuilder() .setHasWideColorGamut(true) .Build())); ui::Rotation orientation = ui::Transform::toRotation(args.renderArea.getRotationFlags()); Rect orientedDisplaySpaceRect{args.renderArea.getReqWidth(), args.renderArea.getReqHeight()}; output->setProjection(orientation, args.renderArea.getLayerStackSpaceRect(), orientedDisplaySpaceRect); Rect sourceCrop = args.renderArea.getSourceCrop(); output->setDisplaySize({sourceCrop.getWidth(), sourceCrop.getHeight()}); return output; } ScreenCaptureOutput::ScreenCaptureOutput(ScreenCaptureOutputArgs&& args) : mRenderArea(args.renderArea), mFilterForScreenshot(std::move(args.filterForScreenshot)), mColorProfile(args.colorProfile), mRegionSampling(args.regionSampling) {} void ScreenCaptureOutput::updateColorProfile(const compositionengine::CompositionRefreshArgs&) { auto& outputState = editState(); outputState.dataspace = mColorProfile.dataspace; outputState.renderIntent = mColorProfile.renderIntent; } renderengine::DisplaySettings ScreenCaptureOutput::generateClientCompositionDisplaySettings() const { auto clientCompositionDisplay = compositionengine::impl::Output::generateClientCompositionDisplaySettings(); clientCompositionDisplay.clip = mRenderArea.getSourceCrop(); clientCompositionDisplay.targetLuminanceNits = -1; return clientCompositionDisplay; } std::vector ScreenCaptureOutput::generateClientCompositionRequests( bool supportsProtectedContent, ui::Dataspace outputDataspace, std::vector& outLayerFEs) { auto clientCompositionLayers = compositionengine::impl::Output:: generateClientCompositionRequests(supportsProtectedContent, outputDataspace, outLayerFEs); if (mRegionSampling) { for (auto& layer : clientCompositionLayers) { layer.backgroundBlurRadius = 0; layer.blurRegions.clear(); } } Rect sourceCrop = mRenderArea.getSourceCrop(); compositionengine::LayerFE::LayerSettings fillLayer; fillLayer.source.buffer.buffer = nullptr; fillLayer.source.solidColor = half3(0.0f, 0.0f, 0.0f); fillLayer.geometry.boundaries = FloatRect(static_cast(sourceCrop.left), static_cast(sourceCrop.top), static_cast(sourceCrop.right), static_cast(sourceCrop.bottom)); fillLayer.alpha = half(RenderArea::getCaptureFillValue(mRenderArea.getCaptureFill())); clientCompositionLayers.insert(clientCompositionLayers.begin(), fillLayer); return clientCompositionLayers; } bool ScreenCaptureOutput::layerNeedsFiltering(const compositionengine::OutputLayer* layer) const { return mRenderArea.needsFiltering() || mFilterForScreenshot.find(&layer->getLayerFE()) != mFilterForScreenshot.end(); } } // namespace android