/*
 * Copyright (C) 2013 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 "RenderProxy.h"

#include <gui/TraceUtils.h>
#include "DeferredLayerUpdater.h"
#include "DisplayList.h"
#include "Properties.h"
#include "Readback.h"
#include "Rect.h"
#include "WebViewFunctorManager.h"
#include "renderthread/CanvasContext.h"
#include "renderthread/RenderTask.h"
#include "renderthread/RenderThread.h"
#include "utils/Macros.h"
#include "utils/TimeUtils.h"

#include <SkBitmap.h>
#include <SkImage.h>
#include <SkPicture.h>

#include <pthread.h>

namespace android {
namespace uirenderer {
namespace renderthread {

RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode,
                         IContextFactory* contextFactory)
        : mRenderThread(RenderThread::getInstance()), mContext(nullptr) {
    pid_t uiThreadId = pthread_gettid_np(pthread_self());
    pid_t renderThreadId = getRenderThreadTid();
    mContext = mRenderThread.queue().runSync([=, this]() -> CanvasContext* {
        CanvasContext* context = CanvasContext::create(mRenderThread, translucent, rootRenderNode,
                                                       contextFactory, uiThreadId, renderThreadId);
        if (context != nullptr) {
            mRenderThread.queue().post([=] { context->startHintSession(); });
        }
        return context;
    });
    mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode);
}

RenderProxy::~RenderProxy() {
    destroyContext();
}

void RenderProxy::destroyContext() {
    if (mContext) {
        mDrawFrameTask.setContext(nullptr, nullptr, nullptr);
        // This is also a fence as we need to be certain that there are no
        // outstanding mDrawFrame tasks posted before it is destroyed
        mRenderThread.queue().runSync([this]() { delete mContext; });
        mContext = nullptr;
    }
}

void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) {
    mRenderThread.queue().post([this, swapBehavior]() { mContext->setSwapBehavior(swapBehavior); });
}

bool RenderProxy::loadSystemProperties() {
    return mRenderThread.queue().runSync([this]() -> bool {
        bool needsRedraw = Properties::load();
        if (mContext->profiler().consumeProperties()) {
            needsRedraw = true;
        }
        return needsRedraw;
    });
}

void RenderProxy::setName(const char* name) {
    // block since name/value pointers owned by caller
    // TODO: Support move arguments
    mRenderThread.queue().runSync([this, name]() { mContext->setName(std::string(name)); });
}

void RenderProxy::setHardwareBuffer(AHardwareBuffer* buffer) {
    if (buffer) {
        AHardwareBuffer_acquire(buffer);
    }
    mRenderThread.queue().post([this, hardwareBuffer = buffer]() mutable {
        mContext->setHardwareBuffer(hardwareBuffer);
        if (hardwareBuffer) {
            AHardwareBuffer_release(hardwareBuffer);
        }
    });
}

void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) {
    if (window) { ANativeWindow_acquire(window); }
    mRenderThread.queue().post([this, win = window, enableTimeout]() mutable {
        mContext->setSurface(win, enableTimeout);
        if (win) { ANativeWindow_release(win); }
    });
}

void RenderProxy::setSurfaceControl(ASurfaceControl* surfaceControl) {
    auto funcs = mRenderThread.getASurfaceControlFunctions();
    if (surfaceControl) {
        funcs.acquireFunc(surfaceControl);
    }
    mRenderThread.queue().post([this, control = surfaceControl, funcs]() mutable {
        mContext->setSurfaceControl(control);
        if (control) {
            funcs.releaseFunc(control);
        }
    });
}

void RenderProxy::allocateBuffers() {
    mRenderThread.queue().post([=]() { mContext->allocateBuffers(); });
}

bool RenderProxy::pause() {
    return mRenderThread.queue().runSync([this]() -> bool { return mContext->pauseSurface(); });
}

void RenderProxy::setStopped(bool stopped) {
    mRenderThread.queue().runSync([this, stopped]() { mContext->setStopped(stopped); });
}

void RenderProxy::setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
    mRenderThread.queue().post(
            [=]() { mContext->setLightAlpha(ambientShadowAlpha, spotShadowAlpha); });
}

void RenderProxy::setLightGeometry(const Vector3& lightCenter, float lightRadius) {
    mRenderThread.queue().post([=]() { mContext->setLightGeometry(lightCenter, lightRadius); });
}

void RenderProxy::setOpaque(bool opaque) {
    mRenderThread.queue().post([=]() { mContext->setOpaque(opaque); });
}

float RenderProxy::setColorMode(ColorMode mode) {
    // We only need to figure out what the renderer supports for HDR, otherwise this can stay
    // an async call since we already know the return value
    if (mode == ColorMode::Hdr || mode == ColorMode::Hdr10) {
        return mRenderThread.queue().runSync(
                [=]() -> float { return mContext->setColorMode(mode); });
    } else {
        mRenderThread.queue().post([=]() { mContext->setColorMode(mode); });
        return 1.f;
    }
}

void RenderProxy::setRenderSdrHdrRatio(float ratio) {
    mDrawFrameTask.setRenderSdrHdrRatio(ratio);
}

int64_t* RenderProxy::frameInfo() {
    return mDrawFrameTask.frameInfo();
}

void RenderProxy::forceDrawNextFrame() {
    mDrawFrameTask.forceDrawNextFrame();
}

int RenderProxy::syncAndDrawFrame() {
    return mDrawFrameTask.drawFrame();
}

void RenderProxy::destroy() {
    // destroyCanvasAndSurface() needs a fence as when it returns the
    // underlying BufferQueue is going to be released from under
    // the render thread.
    mRenderThread.queue().runSync([=]() { mContext->destroy(); });
}

void RenderProxy::destroyFunctor(int functor) {
    ATRACE_CALL();
    RenderThread& thread = RenderThread::getInstance();
    thread.queue().post([=]() { WebViewFunctorManager::instance().destroyFunctor(functor); });
}

DeferredLayerUpdater* RenderProxy::createTextureLayer() {
    return mRenderThread.queue().runSync([this]() -> auto {
        return mContext->createTextureLayer();
    });
}

void RenderProxy::buildLayer(RenderNode* node) {
    mRenderThread.queue().runSync([&]() { mContext->buildLayer(node); });
}

bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
    ATRACE_NAME("TextureView#getBitmap");
    auto& thread = RenderThread::getInstance();
    return thread.queue().runSync([&]() -> bool {
        return thread.readback().copyLayerInto(layer, &bitmap) == CopyResult::Success;
    });
}

void RenderProxy::pushLayerUpdate(DeferredLayerUpdater* layer) {
    mDrawFrameTask.pushLayerUpdate(layer);
}

void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) {
    mDrawFrameTask.removeLayerUpdate(layer);
}

void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) {
    return mRenderThread.queue().runSync([&]() { layer->detachSurfaceTexture(); });
}

void RenderProxy::destroyHardwareResources() {
    return mRenderThread.queue().runSync([&]() { mContext->destroyHardwareResources(); });
}

void RenderProxy::trimMemory(int level) {
    // Avoid creating a RenderThread to do a trimMemory.
    if (RenderThread::hasInstance()) {
        RenderThread& thread = RenderThread::getInstance();
        const auto trimLevel = static_cast<TrimLevel>(level);
        thread.queue().post([&thread, trimLevel]() { thread.trimMemory(trimLevel); });
    }
}

void RenderProxy::purgeCaches() {
    if (RenderThread::hasInstance()) {
        RenderThread& thread = RenderThread::getInstance();
        thread.queue().post([&thread]() {
            if (thread.getGrContext()) {
                thread.cacheManager().trimMemory(TrimLevel::COMPLETE);
            }
        });
    }
}

void RenderProxy::overrideProperty(const char* name, const char* value) {
    // expensive, but block here since name/value pointers owned by caller
    RenderThread::getInstance().queue().runSync(
            [&]() { Properties::overrideProperty(name, value); });
}

void RenderProxy::fence() {
    mRenderThread.queue().runSync([]() {});
}

int RenderProxy::maxTextureSize() {
    static int maxTextureSize = RenderThread::getInstance().queue().runSync(
            []() { return DeviceInfo::get()->maxTextureSize(); });
    return maxTextureSize;
}

void RenderProxy::stopDrawing() {
    mRenderThread.queue().runSync([this]() { mContext->stopDrawing(); });
}

void RenderProxy::notifyFramePending() {
    mRenderThread.queue().post([this]() { mContext->notifyFramePending(); });
}

void RenderProxy::notifyCallbackPending() {
    mRenderThread.queue().post([this]() { mContext->sendLoadResetHint(); });
}

void RenderProxy::notifyExpensiveFrame() {
    mRenderThread.queue().post([this]() { mContext->sendLoadIncreaseHint(); });
}

void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) {
    mRenderThread.queue().runSync([&]() {
        std::lock_guard lock(mRenderThread.getJankDataMutex());
        mContext->profiler().dumpData(fd);
        if (dumpFlags & DumpFlags::FrameStats) {
            mContext->dumpFrames(fd);
        }
        if (dumpFlags & DumpFlags::JankStats) {
            mRenderThread.globalProfileData()->dump(fd);
        }
        if (dumpFlags & DumpFlags::Reset) {
            mContext->resetFrameStats();
        }
    });
}

void RenderProxy::resetProfileInfo() {
    mRenderThread.queue().runSync([=]() {
        std::lock_guard lock(mRenderThread.getJankDataMutex());
        mContext->resetFrameStats();
    });
}

uint32_t RenderProxy::frameTimePercentile(int percentile) {
    return mRenderThread.queue().runSync([&]() -> auto {
        std::lock_guard lock(mRenderThread.globalProfileData().getDataMutex());
        return mRenderThread.globalProfileData()->findPercentile(percentile);
    });
}

void RenderProxy::dumpGraphicsMemory(int fd, bool includeProfileData, bool resetProfile) {
    if (RenderThread::hasInstance()) {
        auto& thread = RenderThread::getInstance();
        thread.queue().runSync([&]() {
            thread.dumpGraphicsMemory(fd, includeProfileData);
            if (resetProfile) {
                thread.globalProfileData()->reset();
            }
        });
    }
}

void RenderProxy::getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage) {
    if (RenderThread::hasInstance()) {
        auto& thread = RenderThread::getInstance();
        thread.queue().runSync([&]() { thread.getMemoryUsage(cpuUsage, gpuUsage); });
    }
}

void RenderProxy::setProcessStatsBuffer(int fd) {
    auto& rt = RenderThread::getInstance();
    rt.queue().post([&rt, fd = dup(fd)]() {
        rt.globalProfileData().switchStorageToAshmem(fd);
        close(fd);
    });
}

void RenderProxy::rotateProcessStatsBuffer() {
    auto& rt = RenderThread::getInstance();
    rt.queue().post([&rt]() { rt.globalProfileData().rotateStorage(); });
}

int RenderProxy::getRenderThreadTid() {
    return mRenderThread.getTid();
}

void RenderProxy::addRenderNode(RenderNode* node, bool placeFront) {
    mRenderThread.queue().post([=]() { mContext->addRenderNode(node, placeFront); });
}

void RenderProxy::removeRenderNode(RenderNode* node) {
    mRenderThread.queue().post([=]() { mContext->removeRenderNode(node); });
}

void RenderProxy::drawRenderNode(RenderNode* node) {
    mRenderThread.queue().runSync([=]() { mContext->prepareAndDraw(node); });
}

void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom) {
    mDrawFrameTask.setContentDrawBounds(left, top, right, bottom);
}

void RenderProxy::setHardwareBufferRenderParams(const HardwareBufferRenderParams& params) {
    mDrawFrameTask.setHardwareBufferRenderParams(params);
}

void RenderProxy::setPictureCapturedCallback(
        const std::function<void(sk_sp<SkPicture>&&)>& callback) {
    mRenderThread.queue().post(
            [this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
}

void RenderProxy::setASurfaceTransactionCallback(
        const std::function<bool(int64_t, int64_t, int64_t)>& callback) {
    mRenderThread.queue().post(
            [this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); });
}

void RenderProxy::setPrepareSurfaceControlForWebviewCallback(
        const std::function<void()>& callback) {
    mRenderThread.queue().post(
            [this, cb = callback]() { mContext->setPrepareSurfaceControlForWebviewCallback(cb); });
}

void RenderProxy::setFrameCallback(
        std::function<std::function<void(bool)>(int32_t, int64_t)>&& callback) {
    mDrawFrameTask.setFrameCallback(std::move(callback));
}

void RenderProxy::setFrameCommitCallback(std::function<void(bool)>&& callback) {
    mDrawFrameTask.setFrameCommitCallback(std::move(callback));
}

void RenderProxy::setFrameCompleteCallback(std::function<void()>&& callback) {
    mDrawFrameTask.setFrameCompleteCallback(std::move(callback));
}

void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
    mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
        mContext->addFrameMetricsObserver(observer.get());
    });
}

void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
    mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
        mContext->removeFrameMetricsObserver(observer.get());
    });
}

void RenderProxy::setForceDark(bool enable) {
    mRenderThread.queue().post([this, enable]() { mContext->setForceDark(enable); });
}

void RenderProxy::copySurfaceInto(ANativeWindow* window, std::shared_ptr<CopyRequest>&& request) {
    auto& thread = RenderThread::getInstance();
    ANativeWindow_acquire(window);
    thread.queue().post([&thread, window, request = std::move(request)] {
        thread.readback().copySurfaceInto(window, request);
        ANativeWindow_release(window);
    });
}

void RenderProxy::prepareToDraw(Bitmap& bitmap) {
    // If we haven't spun up a hardware accelerated window yet, there's no
    // point in precaching these bitmaps as it can't impact jank.
    // We also don't know if we even will spin up a hardware-accelerated
    // window or not.
    if (!RenderThread::hasInstance()) return;
    RenderThread* renderThread = &RenderThread::getInstance();
    bitmap.ref();
    auto task = [renderThread, &bitmap]() {
        CanvasContext::prepareToDraw(*renderThread, &bitmap);
        bitmap.unref();
    };
    nsecs_t lastVsync = renderThread->timeLord().latestVsync();
    nsecs_t estimatedNextVsync = lastVsync + renderThread->timeLord().frameIntervalNanos();
    nsecs_t timeToNextVsync = estimatedNextVsync - systemTime(SYSTEM_TIME_MONOTONIC);
    // We expect the UI thread to take 4ms and for RT to be active from VSYNC+4ms to
    // VSYNC+12ms or so, so aim for the gap during which RT is expected to
    // be idle
    // TODO: Make this concept a first-class supported thing? RT could use
    // knowledge of pending draws to better schedule this task
    if (timeToNextVsync > -6_ms && timeToNextVsync < 1_ms) {
        renderThread->queue().postAt(estimatedNextVsync + 8_ms, task);
    } else {
        renderThread->queue().post(task);
    }
}

int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) {
    ATRACE_NAME("HardwareBitmap readback");
    RenderThread& thread = RenderThread::getInstance();
    if (gettid() == thread.getTid()) {
        // TODO: fix everything that hits this. We should never be triggering a readback ourselves.
        return (int)thread.readback().copyHWBitmapInto(hwBitmap, bitmap);
    } else {
        return thread.queue().runSync(
                [&]() -> int { return (int)thread.readback().copyHWBitmapInto(hwBitmap, bitmap); });
    }
}

int RenderProxy::copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap) {
    RenderThread& thread = RenderThread::getInstance();
    if (gettid() == thread.getTid()) {
        // TODO: fix everything that hits this. We should never be triggering a readback ourselves.
        return (int)thread.readback().copyImageInto(image, bitmap);
    } else {
        return thread.queue().runSync(
                [&]() -> int { return (int)thread.readback().copyImageInto(image, bitmap); });
    }
}

void RenderProxy::disableVsync() {
    Properties::disableVsync = true;
}

void RenderProxy::preload() {
    // Create RenderThread object and start the thread. Then preload Vulkan/EGL driver.
    auto& thread = RenderThread::getInstance();
    thread.queue().post([&thread]() { thread.preload(); });
}

void RenderProxy::setRtAnimationsEnabled(bool enabled) {
    if (RenderThread::hasInstance()) {
        RenderThread::getInstance().queue().post(
                [enabled]() { Properties::enableRTAnimations = enabled; });
    } else {
        Properties::enableRTAnimations = enabled;
    }
}

} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
