/*
 * Copyright (C) 2010 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.
 */

package android.graphics;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Pools.SynchronizedPool;
import android.view.DisplayListCanvas;
import android.view.TextureLayer;

import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;

/**
 * A Canvas implementation that records view system drawing operations for deferred rendering.
 * This is used in combination with RenderNode. This class keeps a list of all the Paint and
 * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being released while
 * the RecordingCanvas is still holding a native reference to the memory.
 *
 * This is obtained by calling {@link RenderNode#beginRecording()} and is valid until the matching
 * {@link RenderNode#endRecording()} is called. It must not be retained beyond that as it is
 * internally reused.
 */
public final class RecordingCanvas extends DisplayListCanvas {
    // The recording canvas pool should be large enough to handle a deeply nested
    // view hierarchy because display lists are generated recursively.
    private static final int POOL_LIMIT = 25;

    /** @hide */
    public static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB

    private static final SynchronizedPool<RecordingCanvas> sPool =
            new SynchronizedPool<>(POOL_LIMIT);

    /**
     * TODO: Temporarily exposed for RenderNodeAnimator(Set)
     * @hide */
    public RenderNode mNode;
    private int mWidth;
    private int mHeight;

    /** @hide */
    static RecordingCanvas obtain(@NonNull RenderNode node, int width, int height) {
        if (node == null) throw new IllegalArgumentException("node cannot be null");
        RecordingCanvas canvas = sPool.acquire();
        if (canvas == null) {
            canvas = new RecordingCanvas(node, width, height);
        } else {
            nResetDisplayListCanvas(canvas.mNativeCanvasWrapper, node.mNativeRenderNode,
                    width, height);
        }
        canvas.mNode = node;
        canvas.mWidth = width;
        canvas.mHeight = height;
        return canvas;
    }

    /** @hide */
    void recycle() {
        mNode = null;
        sPool.release(this);
    }

    /** @hide */
    long finishRecording() {
        return nFinishRecording(mNativeCanvasWrapper);
    }

    /** @hide */
    @Override
    public boolean isRecordingFor(Object o) {
        return o == mNode;
    }

    ///////////////////////////////////////////////////////////////////////////
    // Constructors
    ///////////////////////////////////////////////////////////////////////////

    /** @hide */
    protected RecordingCanvas(@NonNull RenderNode node, int width, int height) {
        super(nCreateDisplayListCanvas(node.mNativeRenderNode, width, height));
        mDensity = 0; // disable bitmap density scaling
    }

    ///////////////////////////////////////////////////////////////////////////
    // Canvas management
    ///////////////////////////////////////////////////////////////////////////


    @Override
    public void setDensity(int density) {
        // drop silently, since RecordingCanvas doesn't perform density scaling
    }

    @Override
    public boolean isHardwareAccelerated() {
        return true;
    }

    @Override
    public void setBitmap(Bitmap bitmap) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isOpaque() {
        return false;
    }

    @Override
    public int getWidth() {
        return mWidth;
    }

    @Override
    public int getHeight() {
        return mHeight;
    }

    @Override
    public int getMaximumBitmapWidth() {
        return nGetMaximumTextureWidth();
    }

    @Override
    public int getMaximumBitmapHeight() {
        return nGetMaximumTextureHeight();
    }

    ///////////////////////////////////////////////////////////////////////////
    // Setup
    ///////////////////////////////////////////////////////////////////////////

    @Override
    public void enableZ() {
        nInsertReorderBarrier(mNativeCanvasWrapper, true);
    }

    @Override
    public void disableZ() {
        nInsertReorderBarrier(mNativeCanvasWrapper, false);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Functor
    ///////////////////////////////////////////////////////////////////////////

    /**
     * Records the functor specified with the drawGLFunction function pointer. This is
     * functionality used by webview for calling into their renderer from our display lists.
     *
     * @param drawGLFunction A native function pointer
     *
     * @hide
     * @deprecated Use {@link #drawWebViewFunctor(int)}
     */
    @Deprecated
    public void callDrawGLFunction2(long drawGLFunction) {
        nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction, null);
    }

    /**
     * Records the functor specified with the drawGLFunction function pointer. This is
     * functionality used by webview for calling into their renderer from our display lists.
     *
     * @param drawGLFunctor A native function pointer
     * @param releasedCallback Called when the display list is destroyed, and thus
     * the functor is no longer referenced by this canvas's display list.
     *
     * NOTE: The callback does *not* necessarily mean that there are no longer
     * any references to the functor, just that the reference from this specific
     * canvas's display list has been released.
     *
     * @hide
     * @deprecated Use {@link #drawWebViewFunctor(int)}
     */
    @Deprecated
    public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
        nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback);
    }

    /**
     * Calls the provided functor that was created via WebViewFunctor_create()
     * @hide
     */
    public void drawWebViewFunctor(int functor) {
        nDrawWebViewFunctor(mNativeCanvasWrapper, functor);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Display list
    ///////////////////////////////////////////////////////////////////////////

    /**
     * Draws the specified display list onto this canvas.
     *
     * @param renderNode The RenderNode to draw.
     */
    @Override
    public void drawRenderNode(@NonNull RenderNode renderNode) {
        nDrawRenderNode(mNativeCanvasWrapper, renderNode.mNativeRenderNode);
    }

    ///////////////////////////////////////////////////////////////////////////
    // Hardware layer
    ///////////////////////////////////////////////////////////////////////////

    /**
     * Draws the specified layer onto this canvas.
     *
     * @param layer The layer to composite on this canvas
     * @hide
     */
    public void drawTextureLayer(TextureLayer layer) {
        nDrawTextureLayer(mNativeCanvasWrapper, layer.getLayerHandle());
    }

    ///////////////////////////////////////////////////////////////////////////
    // Drawing
    ///////////////////////////////////////////////////////////////////////////

    /**
     * Draws a circle
     *
     * @param cx
     * @param cy
     * @param radius
     * @param paint
     *
     * @hide
     */
    public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
            CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
        nDrawCircle(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
                radius.getNativeContainer(), paint.getNativeContainer());
    }

    /**
     * Draws a round rect
     *
     * @param left
     * @param top
     * @param right
     * @param bottom
     * @param rx
     * @param ry
     * @param paint
     *
     * @hide
     */
    public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
            CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
            CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
        nDrawRoundRect(mNativeCanvasWrapper, left.getNativeContainer(), top.getNativeContainer(),
                right.getNativeContainer(), bottom.getNativeContainer(),
                rx.getNativeContainer(), ry.getNativeContainer(),
                paint.getNativeContainer());
    }

    /** @hide */
    @Override
    protected void throwIfCannotDraw(Bitmap bitmap) {
        super.throwIfCannotDraw(bitmap);
        int bitmapSize = bitmap.getByteCount();
        if (bitmapSize > MAX_BITMAP_SIZE) {
            throw new RuntimeException(
                    "Canvas: trying to draw too large(" + bitmapSize + "bytes) bitmap.");
        }
    }


    // ------------------ Fast JNI ------------------------

    @FastNative
    private static native void nCallDrawGLFunction(long renderer,
            long drawGLFunction, Runnable releasedCallback);


    // ------------------ Critical JNI ------------------------

    @CriticalNative
    private static native long nCreateDisplayListCanvas(long node, int width, int height);
    @CriticalNative
    private static native void nResetDisplayListCanvas(long canvas, long node,
            int width, int height);
    @CriticalNative
    private static native int nGetMaximumTextureWidth();
    @CriticalNative
    private static native int nGetMaximumTextureHeight();
    @CriticalNative
    private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
    @CriticalNative
    private static native long nFinishRecording(long renderer);
    @CriticalNative
    private static native void nDrawRenderNode(long renderer, long renderNode);
    @CriticalNative
    private static native void nDrawTextureLayer(long renderer, long layer);
    @CriticalNative
    private static native void nDrawCircle(long renderer, long propCx,
            long propCy, long propRadius, long propPaint);
    @CriticalNative
    private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
            long propRight, long propBottom, long propRx, long propRy, long propPaint);
    @CriticalNative
    private static native void nDrawWebViewFunctor(long canvas, int functor);
}
