/*
 * Copyright 2017 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.cts;

import static org.junit.Assert.assertEquals;

//import static android.opengl.EGL14.*;
//import static android.opengl.EGL15.*;
import android.opengl.EGL14;
import android.opengl.EGL15;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLImage;
import android.opengl.EGLSurface;
import android.opengl.EGLSync;
import android.opengl.GLES20;
import android.os.SystemProperties;

import androidx.test.filters.SmallTest;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;

@SmallTest
@RunWith(BlockJUnit4ClassRunner.class)
public class EGL15Test {

    static {
        System.loadLibrary("ctsgraphics_jni");
    }

    private static final String TAG = EGL15Test.class.getSimpleName();
    private static final boolean DEBUG = false;

    private EGLDisplay mEglDisplay = EGL15.EGL_NO_DISPLAY;
    private EGLConfig mEglConfig = null;
    private EGLSurface mEglPbuffer = EGL15.EGL_NO_SURFACE;
    private EGLContext mEglContext = EGL15.EGL_NO_CONTEXT;
    private int mEglVersion = 0;

    @Before
    public void setup() throws Throwable {
        int error;

        mEglDisplay = EGL15.eglGetPlatformDisplay(EGL15.EGL_PLATFORM_ANDROID_KHR,
                EGL14.EGL_DEFAULT_DISPLAY,
                new long[] {
                    EGL14.EGL_NONE },
                0);
        if (mEglDisplay == EGL15.EGL_NO_DISPLAY) {
            throw new RuntimeException("no EGL display");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglGetPlatformDisplay failed");
        }

        int[] major = new int[1];
        int[] minor = new int[1];
        if (!EGL14.eglInitialize(mEglDisplay, major, 0, minor, 0)) {
            throw new RuntimeException("error in eglInitialize");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglInitialize failed");
        }
        mEglVersion = major[0] * 10 + minor[0];

        // If we could rely on having EGL_KHR_surfaceless_context and EGL_KHR_context_no_config, we
        // wouldn't have to create a config or pbuffer at all.

        int[] numConfigs = new int[1];
        EGLConfig[] configs = new EGLConfig[1];
        if (!EGL14.eglChooseConfig(mEglDisplay,
                new int[] {
                    EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
                    EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT,
                    EGL14.EGL_NONE},
                0, configs, 0, 1, numConfigs, 0)) {
            throw new RuntimeException("eglChooseConfig failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglChooseConfig failed");
        }

        mEglConfig = configs[0];

        mEglPbuffer = EGL14.eglCreatePbufferSurface(mEglDisplay, mEglConfig,
                new int[] {EGL14.EGL_WIDTH, 1, EGL14.EGL_HEIGHT, 1, EGL14.EGL_NONE}, 0);
        if (mEglPbuffer == EGL15.EGL_NO_SURFACE) {
            throw new RuntimeException("eglCreatePbufferSurface failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglCreatePbufferSurface failed");
        }


        mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT,
                new int[] {EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE}, 0);
        if (mEglContext == EGL15.EGL_NO_CONTEXT) {
            throw new RuntimeException("eglCreateContext failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglCreateContext failed");
        }


        if (!EGL14.eglMakeCurrent(mEglDisplay, mEglPbuffer, mEglPbuffer, mEglContext)) {
            throw new RuntimeException("eglMakeCurrent failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglMakeCurrent failed");
        }
    }

    @After
    public void teardown() throws Throwable {
        EGL14.eglTerminate(mEglDisplay);
    }

    @Test
    public void testEGL15SyncFence() {
        if (mEglVersion < 15) {
            return;
        }
        EGLSync sync = EGL15.eglCreateSync(mEglDisplay, EGL15.EGL_SYNC_FENCE,
                new long[] {
                    EGL14.EGL_NONE },
                0);
        if (sync == EGL15.EGL_NO_SYNC) {
            throw new RuntimeException("eglCreateSync failed");
        }
        int error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglCreateSync failed");
        }

        GLES20.glFlush();
        error = GLES20.glGetError();
        if (error != GLES20.GL_NO_ERROR) {
            throw new RuntimeException("glFlush failed");
        }

        int status = EGL15.eglClientWaitSync(mEglDisplay, sync, 0, EGL15.EGL_FOREVER);
        if (status != EGL15.EGL_CONDITION_SATISFIED) {
            throw new RuntimeException("eglClientWaitSync failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglClientWaitSync failed");
        }

        if (!EGL15.eglDestroySync(mEglDisplay, sync)) {
            throw new RuntimeException("eglDestroySync failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglDestroySync failed");
        }
    }

    @Test
    public void testEGL15GetSyncType() {
        if (mEglVersion < 15) {
            return;
        }
        EGLSync sync = EGL15.eglCreateSync(mEglDisplay, EGL15.EGL_SYNC_FENCE,
                new long[] {
                    EGL14.EGL_NONE },
                0);
        if (sync == EGL15.EGL_NO_SYNC) {
            throw new RuntimeException("eglCreateSync failed");
        }
        int error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglCreateSync failed");
        }

        long[] type = new long[1];
        boolean success = EGL15.eglGetSyncAttrib(mEglDisplay, sync, EGL15.EGL_SYNC_TYPE, type, 0);
        if (!success) {
            throw new RuntimeException("eglGetSyncAttrib failed (returned false)");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglGetSyncAttrib failed");
        }
        assertEquals(type[0], EGL15.EGL_SYNC_FENCE);

        if (!EGL15.eglDestroySync(mEglDisplay, sync)) {
            throw new RuntimeException("eglDestroySync failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglDestroySync failed");
        }
    }

    @Test
    public void testEGL15WaitSync() {
        if (mEglVersion < 15) {
            return;
        }
        EGLSync sync = EGL15.eglCreateSync(mEglDisplay, EGL15.EGL_SYNC_FENCE,
                new long[] {
                    EGL14.EGL_NONE },
                0);
        if (sync == EGL15.EGL_NO_SYNC) {
            throw new RuntimeException("eglCreateSync failed");
        }
        int error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglCreateSync failed");
        }

        boolean success = EGL15.eglWaitSync(mEglDisplay, sync, 0);
        if (!success) {
            throw new RuntimeException("eglWaitSync failed (returned false)");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglWaitSync failed");
        }

        if (!EGL15.eglDestroySync(mEglDisplay, sync)) {
            throw new RuntimeException("eglDestroySync failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglDestroySync failed");
        }
    }

    @Test
    public void testEGL15CreateImage() {
        if (mEglVersion < 15) {
            return;
        }

        int error;
        int srcTex = 1;
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, srcTex);
        error = GLES20.glGetError();
        if (error != GLES20.GL_NO_ERROR) {
            throw new RuntimeException("glBindTexture failed");
        }

        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 64, 64, 0,
                            GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
        error = GLES20.glGetError();
        if (error != GLES20.GL_NO_ERROR) {
            throw new RuntimeException("glTexImage2D failed");
        }

        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
                               GLES20.GL_LINEAR);
        error = GLES20.glGetError();
        if (error != GLES20.GL_NO_ERROR) {
            throw new RuntimeException("glTexParameteri failed");
        }

        long[] attribs = new long[] {
                EGL15.EGL_GL_TEXTURE_LEVEL, 0,
                EGL14.EGL_NONE };
        EGLImage image = EGL15.eglCreateImage(mEglDisplay, mEglContext,
                EGL15.EGL_GL_TEXTURE_2D, srcTex, attribs, 0);
        if (image == EGL15.EGL_NO_IMAGE) {
            throw new RuntimeException("eglCreateImage failed, got EGL_NO_IMAGE");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglCreateImage failed");
        }

        boolean success = EGL15.eglDestroyImage(mEglDisplay, image);
        if (!success) {
            throw new RuntimeException("eglDestroyImage failed (returned false)");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglDestroyImage failed");
        }
    }

    @Test
    public void testEGL15CreatePlatformPixmap() {
        if (mEglVersion < 15) {
            return;
        }

        long[] attribs = new long[] { EGL14.EGL_NONE };
        boolean unsupported = false;
        try {
            EGLSurface surface = EGL15.eglCreatePlatformPixmapSurface(mEglDisplay,
                    mEglConfig, null, attribs, 0);
        } catch (UnsupportedOperationException e) {
            unsupported = true;
        }
        if (!unsupported) {
            throw new RuntimeException("eglCreatePlatformPixmapSurface is not supported on Android,"
                    + " why did call not report that!");
        }
    }

    @Test
    public void testEGL15CreateDebugContext() {
        int error;

        if (mEglVersion < 15) {
            return;
        }

        // Required functionality for devices released with Android R (11),
        // skip if launched with older version of Android.
        if (SystemProperties.getInt("ro.product.first_api_level", 0) < 30) {
            return;
        }

        mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT,
                new int[] { EGL15.EGL_CONTEXT_OPENGL_DEBUG, EGL14.EGL_FALSE, EGL14.EGL_NONE }, 0);
        if (mEglContext == EGL15.EGL_NO_CONTEXT) {
            throw new RuntimeException("eglCreateContext failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglCreateContext failed");
        }
        EGL14.eglDestroyContext(mEglDisplay, mEglContext);

        mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT,
                new int[] { EGL15.EGL_CONTEXT_OPENGL_DEBUG, EGL14.EGL_TRUE, EGL14.EGL_NONE }, 0);
        if (mEglContext == EGL15.EGL_NO_CONTEXT) {
            throw new RuntimeException("eglCreateContext failed");
        }
        error = EGL14.eglGetError();
        if (error != EGL14.EGL_SUCCESS) {
            throw new RuntimeException("eglCreateContext failed");
        }
        EGL14.eglDestroyContext(mEglDisplay, mEglContext);
    }
}

// Note: Need to add tests for eglCreatePlatformWindowSurface
