1 /* 2 * Copyright (C) 2007 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 // #define LOG_NDEBUG 0 18 #undef LOG_TAG 19 #define LOG_TAG "ColorLayer" 20 21 #include <stdint.h> 22 #include <stdlib.h> 23 #include <sys/types.h> 24 25 #include <compositionengine/CompositionEngine.h> 26 #include <compositionengine/Display.h> 27 #include <compositionengine/Layer.h> 28 #include <compositionengine/LayerCreationArgs.h> 29 #include <compositionengine/OutputLayer.h> 30 #include <compositionengine/impl/LayerCompositionState.h> 31 #include <compositionengine/impl/OutputLayerCompositionState.h> 32 #include <renderengine/RenderEngine.h> 33 #include <ui/GraphicBuffer.h> 34 #include <utils/Errors.h> 35 #include <utils/Log.h> 36 37 #include "ColorLayer.h" 38 #include "DisplayDevice.h" 39 #include "SurfaceFlinger.h" 40 41 namespace android { 42 // --------------------------------------------------------------------------- 43 44 ColorLayer::ColorLayer(const LayerCreationArgs& args) 45 : Layer(args), 46 mCompositionLayer{mFlinger->getCompositionEngine().createLayer( 47 compositionengine::LayerCreationArgs{this})} {} 48 49 ColorLayer::~ColorLayer() = default; 50 51 bool ColorLayer::prepareClientLayer(const RenderArea& renderArea, const Region& clip, 52 bool useIdentityTransform, Region& clearRegion, 53 const bool supportProtectedContent, 54 renderengine::LayerSettings& layer) { 55 Layer::prepareClientLayer(renderArea, clip, useIdentityTransform, clearRegion, 56 supportProtectedContent, layer); 57 half4 color(getColor()); 58 half3 solidColor(color.r, color.g, color.b); 59 layer.source.solidColor = solidColor; 60 return true; 61 } 62 63 bool ColorLayer::isVisible() const { 64 return !isHiddenByPolicy() && getAlpha() > 0.0f; 65 } 66 67 bool ColorLayer::setColor(const half3& color) { 68 if (mCurrentState.color.r == color.r && mCurrentState.color.g == color.g && 69 mCurrentState.color.b == color.b) { 70 return false; 71 } 72 73 mCurrentState.sequence++; 74 mCurrentState.color.r = color.r; 75 mCurrentState.color.g = color.g; 76 mCurrentState.color.b = color.b; 77 mCurrentState.modified = true; 78 setTransactionFlags(eTransactionNeeded); 79 return true; 80 } 81 82 bool ColorLayer::setDataspace(ui::Dataspace dataspace) { 83 if (mCurrentState.dataspace == dataspace) { 84 return false; 85 } 86 87 mCurrentState.sequence++; 88 mCurrentState.dataspace = dataspace; 89 mCurrentState.modified = true; 90 setTransactionFlags(eTransactionNeeded); 91 return true; 92 } 93 94 void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& display, 95 const ui::Transform& transform, const Rect& viewport, 96 int32_t /* supportedPerFrameMetadata */, 97 const ui::Dataspace targetDataspace) { 98 RETURN_IF_NO_HWC_LAYER(display); 99 100 Region visible = transform.transform(visibleRegion.intersect(viewport)); 101 102 const auto outputLayer = findOutputLayerForDisplay(display); 103 LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc); 104 105 auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer; 106 107 auto error = hwcLayer->setVisibleRegion(visible); 108 if (error != HWC2::Error::None) { 109 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), 110 to_string(error).c_str(), static_cast<int32_t>(error)); 111 visible.dump(LOG_TAG); 112 } 113 outputLayer->editState().visibleRegion = visible; 114 115 setCompositionType(display, Hwc2::IComposerClient::Composition::SOLID_COLOR); 116 117 const ui::Dataspace dataspace = 118 isColorSpaceAgnostic() && targetDataspace != ui::Dataspace::UNKNOWN ? targetDataspace 119 : mCurrentDataSpace; 120 error = hwcLayer->setDataspace(dataspace); 121 if (error != HWC2::Error::None) { 122 ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), dataspace, 123 to_string(error).c_str(), static_cast<int32_t>(error)); 124 } 125 126 auto& layerCompositionState = getCompositionLayer()->editState().frontEnd; 127 layerCompositionState.dataspace = mCurrentDataSpace; 128 129 half4 color = getColor(); 130 error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)), 131 static_cast<uint8_t>(std::round(255.0f * color.g)), 132 static_cast<uint8_t>(std::round(255.0f * color.b)), 255}); 133 if (error != HWC2::Error::None) { 134 ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), 135 static_cast<int32_t>(error)); 136 } 137 layerCompositionState.color = {static_cast<uint8_t>(std::round(255.0f * color.r)), 138 static_cast<uint8_t>(std::round(255.0f * color.g)), 139 static_cast<uint8_t>(std::round(255.0f * color.b)), 255}; 140 141 // Clear out the transform, because it doesn't make sense absent a source buffer 142 error = hwcLayer->setTransform(HWC2::Transform::None); 143 if (error != HWC2::Error::None) { 144 ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(), 145 static_cast<int32_t>(error)); 146 } 147 outputLayer->editState().bufferTransform = static_cast<Hwc2::Transform>(0); 148 149 error = hwcLayer->setColorTransform(getColorTransform()); 150 if (error != HWC2::Error::None) { 151 ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(), 152 to_string(error).c_str(), static_cast<int32_t>(error)); 153 } 154 layerCompositionState.colorTransform = getColorTransform(); 155 156 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); 157 if (error != HWC2::Error::None) { 158 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(), 159 to_string(error).c_str(), static_cast<int32_t>(error)); 160 surfaceDamageRegion.dump(LOG_TAG); 161 } 162 layerCompositionState.surfaceDamage = surfaceDamageRegion; 163 } 164 165 void ColorLayer::commitTransaction(const State& stateToCommit) { 166 Layer::commitTransaction(stateToCommit); 167 mCurrentDataSpace = mDrawingState.dataspace; 168 } 169 170 std::shared_ptr<compositionengine::Layer> ColorLayer::getCompositionLayer() const { 171 return mCompositionLayer; 172 } 173 174 // --------------------------------------------------------------------------- 175 176 }; // namespace android 177