/*
 * 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 <ui/GraphicTypes.h>
#include <ui/Transform.h>

#include "ContainerLayer.h"
#include "DisplayDevice.h"
#include "Layer.h"
#include "LayerRenderArea.h"
#include "SurfaceFlinger.h"

namespace android {
namespace {

struct ReparentForDrawing {
    const sp<Layer>& oldParent;

    ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent,
                       const Rect& drawingBounds)
          : oldParent(oldParent) {
        // Compute and cache the bounds for the new parent layer.
        newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(),
                                 0.f /* shadowRadius */);
        oldParent->setChildrenDrawingParent(newParent);
    }
    ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); }
};

} // namespace

LayerRenderArea::LayerRenderArea(SurfaceFlinger& flinger, sp<Layer> layer, const Rect& crop,
                                 ui::Size reqSize, ui::Dataspace reqDataSpace, bool childrenOnly,
                                 const Rect& layerStackRect, bool allowSecureLayers)
      : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, layerStackRect, allowSecureLayers),
        mLayer(std::move(layer)),
        mCrop(crop),
        mFlinger(flinger),
        mChildrenOnly(childrenOnly) {}

const ui::Transform& LayerRenderArea::getTransform() const {
    return mTransform;
}

Rect LayerRenderArea::getBounds() const {
    return mLayer->getBufferSize(mLayer->getDrawingState());
}

int LayerRenderArea::getHeight() const {
    return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight();
}

int LayerRenderArea::getWidth() const {
    return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth();
}

bool LayerRenderArea::isSecure() const {
    return mAllowSecureLayers;
}

bool LayerRenderArea::needsFiltering() const {
    return mNeedsFiltering;
}

sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const {
    return nullptr;
}

Rect LayerRenderArea::getSourceCrop() const {
    if (mCrop.isEmpty()) {
        return getBounds();
    } else {
        return mCrop;
    }
}

void LayerRenderArea::render(std::function<void()> drawLayers) {
    using namespace std::string_literals;

    const Rect sourceCrop = getSourceCrop();
    // no need to check rotation because there is none
    mNeedsFiltering = sourceCrop.width() != getReqWidth() || sourceCrop.height() != getReqHeight();

    if (!mChildrenOnly) {
        mTransform = mLayer->getTransform().inverse();
        drawLayers();
    } else {
        uint32_t w = static_cast<uint32_t>(getWidth());
        uint32_t h = static_cast<uint32_t>(getHeight());
        // In the "childrenOnly" case we reparent the children to a screenshot
        // layer which has no properties set and which does not draw.
        sp<ContainerLayer> screenshotParentLayer = mFlinger.getFactory().createContainerLayer(
                {&mFlinger, nullptr, "Screenshot Parent"s, w, h, 0, LayerMetadata()});

        ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop);
        drawLayers();
    }
}

} // namespace android
