Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright 2019 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 <android-base/stringprintf.h>
     18 #include <compositionengine/CompositionEngine.h>
     19 #include <compositionengine/DisplayColorProfile.h>
     20 #include <compositionengine/LayerFE.h>
     21 #include <compositionengine/RenderSurface.h>
     22 #include <compositionengine/impl/Output.h>
     23 #include <compositionengine/impl/OutputLayer.h>
     24 #include <ui/DebugUtils.h>
     25 
     26 namespace android::compositionengine {
     27 
     28 Output::~Output() = default;
     29 
     30 namespace impl {
     31 
     32 Output::Output(const CompositionEngine& compositionEngine)
     33       : mCompositionEngine(compositionEngine) {}
     34 
     35 Output::~Output() = default;
     36 
     37 const CompositionEngine& Output::getCompositionEngine() const {
     38     return mCompositionEngine;
     39 }
     40 
     41 bool Output::isValid() const {
     42     return mDisplayColorProfile && mDisplayColorProfile->isValid() && mRenderSurface &&
     43             mRenderSurface->isValid();
     44 }
     45 
     46 const std::string& Output::getName() const {
     47     return mName;
     48 }
     49 
     50 void Output::setName(const std::string& name) {
     51     mName = name;
     52 }
     53 
     54 void Output::setCompositionEnabled(bool enabled) {
     55     if (mState.isEnabled == enabled) {
     56         return;
     57     }
     58 
     59     mState.isEnabled = enabled;
     60     dirtyEntireOutput();
     61 }
     62 
     63 void Output::setProjection(const ui::Transform& transform, int32_t orientation, const Rect& frame,
     64                            const Rect& viewport, const Rect& scissor, bool needsFiltering) {
     65     mState.transform = transform;
     66     mState.orientation = orientation;
     67     mState.scissor = scissor;
     68     mState.frame = frame;
     69     mState.viewport = viewport;
     70     mState.needsFiltering = needsFiltering;
     71 
     72     dirtyEntireOutput();
     73 }
     74 
     75 // TODO(lpique): Rename setSize() once more is moved.
     76 void Output::setBounds(const ui::Size& size) {
     77     mRenderSurface->setDisplaySize(size);
     78     // TODO(lpique): Rename mState.size once more is moved.
     79     mState.bounds = Rect(mRenderSurface->getSize());
     80 
     81     dirtyEntireOutput();
     82 }
     83 
     84 void Output::setLayerStackFilter(uint32_t layerStackId, bool isInternal) {
     85     mState.layerStackId = layerStackId;
     86     mState.layerStackInternal = isInternal;
     87 
     88     dirtyEntireOutput();
     89 }
     90 
     91 void Output::setColorTransform(const mat4& transform) {
     92     if (mState.colorTransformMat == transform) {
     93         return;
     94     }
     95 
     96     const bool isIdentity = (transform == mat4());
     97     const auto newColorTransform =
     98             isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
     99 
    100     mState.colorTransform = newColorTransform;
    101     mState.colorTransformMat = transform;
    102 
    103     dirtyEntireOutput();
    104 }
    105 
    106 void Output::setColorMode(ui::ColorMode mode, ui::Dataspace dataspace,
    107                           ui::RenderIntent renderIntent) {
    108     if (mState.colorMode == mode && mState.dataspace == dataspace &&
    109         mState.renderIntent == renderIntent) {
    110         return;
    111     }
    112 
    113     mState.colorMode = mode;
    114     mState.dataspace = dataspace;
    115     mState.renderIntent = renderIntent;
    116 
    117     mRenderSurface->setBufferDataspace(dataspace);
    118 
    119     ALOGV("Set active color mode: %s (%d), active render intent: %s (%d)",
    120           decodeColorMode(mode).c_str(), mode, decodeRenderIntent(renderIntent).c_str(),
    121           renderIntent);
    122 
    123     dirtyEntireOutput();
    124 }
    125 
    126 void Output::dump(std::string& out) const {
    127     using android::base::StringAppendF;
    128 
    129     StringAppendF(&out, "   Composition Output State: [\"%s\"]", mName.c_str());
    130 
    131     out.append("\n   ");
    132 
    133     dumpBase(out);
    134 }
    135 
    136 void Output::dumpBase(std::string& out) const {
    137     mState.dump(out);
    138 
    139     if (mDisplayColorProfile) {
    140         mDisplayColorProfile->dump(out);
    141     } else {
    142         out.append("    No display color profile!\n");
    143     }
    144 
    145     if (mRenderSurface) {
    146         mRenderSurface->dump(out);
    147     } else {
    148         out.append("    No render surface!\n");
    149     }
    150 
    151     android::base::StringAppendF(&out, "\n   %zu Layers\b", mOutputLayersOrderedByZ.size());
    152     for (const auto& outputLayer : mOutputLayersOrderedByZ) {
    153         if (!outputLayer) {
    154             continue;
    155         }
    156         outputLayer->dump(out);
    157     }
    158 }
    159 
    160 compositionengine::DisplayColorProfile* Output::getDisplayColorProfile() const {
    161     return mDisplayColorProfile.get();
    162 }
    163 
    164 void Output::setDisplayColorProfile(std::unique_ptr<compositionengine::DisplayColorProfile> mode) {
    165     mDisplayColorProfile = std::move(mode);
    166 }
    167 
    168 void Output::setDisplayColorProfileForTest(
    169         std::unique_ptr<compositionengine::DisplayColorProfile> mode) {
    170     mDisplayColorProfile = std::move(mode);
    171 }
    172 
    173 compositionengine::RenderSurface* Output::getRenderSurface() const {
    174     return mRenderSurface.get();
    175 }
    176 
    177 void Output::setRenderSurface(std::unique_ptr<compositionengine::RenderSurface> surface) {
    178     mRenderSurface = std::move(surface);
    179     mState.bounds = Rect(mRenderSurface->getSize());
    180 
    181     dirtyEntireOutput();
    182 }
    183 
    184 void Output::setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface> surface) {
    185     mRenderSurface = std::move(surface);
    186 }
    187 
    188 const OutputCompositionState& Output::getState() const {
    189     return mState;
    190 }
    191 
    192 OutputCompositionState& Output::editState() {
    193     return mState;
    194 }
    195 
    196 Region Output::getDirtyRegion(bool repaintEverything) const {
    197     Region dirty(mState.viewport);
    198     if (!repaintEverything) {
    199         dirty.andSelf(mState.dirtyRegion);
    200     }
    201     return dirty;
    202 }
    203 
    204 bool Output::belongsInOutput(uint32_t layerStackId, bool internalOnly) const {
    205     // The layerStackId's must match, and also the layer must not be internal
    206     // only when not on an internal output.
    207     return (layerStackId == mState.layerStackId) && (!internalOnly || mState.layerStackInternal);
    208 }
    209 
    210 compositionengine::OutputLayer* Output::getOutputLayerForLayer(
    211         compositionengine::Layer* layer) const {
    212     for (const auto& outputLayer : mOutputLayersOrderedByZ) {
    213         if (outputLayer && &outputLayer->getLayer() == layer) {
    214             return outputLayer.get();
    215         }
    216     }
    217     return nullptr;
    218 }
    219 
    220 std::unique_ptr<compositionengine::OutputLayer> Output::getOrCreateOutputLayer(
    221         std::optional<DisplayId> displayId, std::shared_ptr<compositionengine::Layer> layer,
    222         sp<compositionengine::LayerFE> layerFE) {
    223     for (auto& outputLayer : mOutputLayersOrderedByZ) {
    224         if (outputLayer && &outputLayer->getLayer() == layer.get()) {
    225             return std::move(outputLayer);
    226         }
    227     }
    228     return createOutputLayer(mCompositionEngine, displayId, *this, layer, layerFE);
    229 }
    230 
    231 void Output::setOutputLayersOrderedByZ(OutputLayers&& layers) {
    232     mOutputLayersOrderedByZ = std::move(layers);
    233 }
    234 
    235 const Output::OutputLayers& Output::getOutputLayersOrderedByZ() const {
    236     return mOutputLayersOrderedByZ;
    237 }
    238 
    239 void Output::dirtyEntireOutput() {
    240     mState.dirtyRegion.set(mState.bounds);
    241 }
    242 
    243 } // namespace impl
    244 } // namespace android::compositionengine
    245