/*
 * 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.
 */

package android.view;

import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.os.SystemClock;
import android.os.Trace;
import android.view.Surface.OutOfResourcesException;
import android.view.View.AttachInfo;

import java.io.PrintWriter;

/**
 * Hardware renderer that proxies the rendering to a render thread. Most calls
 * are currently synchronous.
 * TODO: Make draw() async.
 * TODO: Figure out how to share the DisplayList between two threads (global lock?)
 *
 * The UI thread can block on the RenderThread, but RenderThread must never
 * block on the UI thread.
 *
 * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
 * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
 * by the lifecycle of the RenderProxy.
 *
 * Note that although currently the EGL context & surfaces are created & managed
 * by the render thread, the goal is to move that into a shared structure that can
 * be managed by both threads. EGLSurface creation & deletion should ideally be
 * done on the UI thread and not the RenderThread to avoid stalling the
 * RenderThread with surface buffer allocation.
 *
 * @hide
 */
public class ThreadedRenderer extends HardwareRenderer {
    private static final String LOGTAG = "ThreadedRenderer";

    private static final Rect NULL_RECT = new Rect(-1, -1, -1, -1);

    private int mWidth, mHeight;
    private long mNativeProxy;

    ThreadedRenderer(boolean translucent) {
        mNativeProxy = nCreateProxy(translucent);
        setEnabled(mNativeProxy != 0);
    }

    @Override
    void destroy(boolean full) {
        nDestroyCanvas(mNativeProxy);
    }

    @Override
    boolean initialize(Surface surface) throws OutOfResourcesException {
        return nInitialize(mNativeProxy, surface);
    }

    @Override
    void updateSurface(Surface surface) throws OutOfResourcesException {
        nUpdateSurface(mNativeProxy, surface);
    }

    @Override
    void destroyLayers(View view) {
        throw new NoSuchMethodError();
    }

    @Override
    void destroyHardwareResources(View view) {
        // TODO: canvas.clearLayerUpdates()
        destroyResources(view);
        // TODO: GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
    }

    private static void destroyResources(View view) {
        view.destroyHardwareResources();

        if (view instanceof ViewGroup) {
            ViewGroup group = (ViewGroup) view;

            int count = group.getChildCount();
            for (int i = 0; i < count; i++) {
                destroyResources(group.getChildAt(i));
            }
        }
    }

    @Override
    void invalidate(Surface surface) {
        updateSurface(surface);
    }

    @Override
    boolean validate() {
        // TODO Remove users of this API
        return false;
    }

    @Override
    boolean safelyRun(Runnable action) {
        // TODO:
        return false;
    }

    @Override
    void setup(int width, int height) {
        mWidth = width;
        mHeight = height;
        nSetup(mNativeProxy, width, height);
    }

    @Override
    int getWidth() {
        return mWidth;
    }

    @Override
    int getHeight() {
        return mHeight;
    }

    @Override
    void dumpGfxInfo(PrintWriter pw) {
        // TODO Auto-generated method stub
    }

    @Override
    long getFrameCount() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    boolean loadSystemProperties() {
        return false;
    }

    @Override
    void pushLayerUpdate(HardwareLayer layer) {
        throw new NoSuchMethodError();
    }

    @Override
    void cancelLayerUpdate(HardwareLayer layer) {
        throw new NoSuchMethodError();
    }

    @Override
    void flushLayerUpdates() {
        throw new NoSuchMethodError();
    }

    /**
     * TODO: Remove
     * Temporary hack to allow RenderThreadTest prototype app to trigger
     * replaying a DisplayList after modifying the displaylist properties
     *
     *  @hide */
    public void repeatLastDraw() {
    }

    @Override
    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) {
        attachInfo.mIgnoreDirtyState = true;
        attachInfo.mDrawingTime = SystemClock.uptimeMillis();
        view.mPrivateFlags |= View.PFLAG_DRAWN;

        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
                == View.PFLAG_INVALIDATED;
        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;

        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
        DisplayList displayList = view.getDisplayList();
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);

        view.mRecreateDisplayList = false;

        if (dirty == null) {
            dirty = NULL_RECT;
        }
        nDrawDisplayList(mNativeProxy, displayList.getNativeDisplayList(),
                dirty.left, dirty.top, dirty.right, dirty.bottom);
    }

    @Override
    HardwareLayer createHardwareLayer(boolean isOpaque) {
        throw new NoSuchMethodError();
    }

    @Override
    HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque) {
        throw new NoSuchMethodError();
    }

    @Override
    SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
        throw new NoSuchMethodError();
    }

    @Override
    void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) {
        throw new NoSuchMethodError();
    }

    @Override
    void detachFunctor(long functor) {
        nDetachFunctor(mNativeProxy, functor);
    }

    @Override
    void attachFunctor(AttachInfo attachInfo, long functor) {
        nAttachFunctor(mNativeProxy, functor);
    }

    @Override
    void setName(String name) {
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            nDeleteProxy(mNativeProxy);
        } finally {
            super.finalize();
        }
    }

    /** @hide */
    public static native void postToRenderThread(Runnable runnable);

    private static native long nCreateProxy(boolean translucent);
    private static native void nDeleteProxy(long nativeProxy);

    private static native boolean nInitialize(long nativeProxy, Surface window);
    private static native void nUpdateSurface(long nativeProxy, Surface window);
    private static native void nSetup(long nativeProxy, int width, int height);
    private static native void nDrawDisplayList(long nativeProxy, long displayList,
            int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
    private static native void nDestroyCanvas(long nativeProxy);

    private static native void nAttachFunctor(long nativeProxy, long functor);
    private static native void nDetachFunctor(long nativeProxy, long functor);
}
