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

#define LOG_TAG "Camera2-Legacy-PerfMeasurement-JNI"
#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/Trace.h>
#include <utils/Vector.h>

#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include "core_jni_helpers.h"

#include <ui/GraphicBuffer.h>
#include <system/window.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

using namespace android;

// fully-qualified class name
#define PERF_MEASUREMENT_CLASS_NAME "android/hardware/camera2/legacy/PerfMeasurement"

/** GL utility methods copied from com_google_android_gles_jni_GLImpl.cpp */

// Check if the extension at the head of pExtensions is pExtension. Note that pExtensions is
// terminated by either 0 or space, while pExtension is terminated by 0.

static bool
extensionEqual(const GLubyte* pExtensions, const GLubyte* pExtension) {
    while (true) {
        char a = *pExtensions++;
        char b = *pExtension++;
        bool aEnd = a == '\0' || a == ' ';
        bool bEnd = b == '\0';
        if (aEnd || bEnd) {
            return aEnd == bEnd;
        }
        if (a != b) {
            return false;
        }
    }
}

static const GLubyte*
nextExtension(const GLubyte* pExtensions) {
    while (true) {
        char a = *pExtensions++;
        if (a == '\0') {
            return pExtensions-1;
        } else if ( a == ' ') {
            return pExtensions;
        }
    }
}

static bool
checkForExtension(const GLubyte* pExtensions, const GLubyte* pExtension) {
    for (; *pExtensions != '\0'; pExtensions = nextExtension(pExtensions)) {
        if (extensionEqual(pExtensions, pExtension)) {
            return true;
        }
    }
    return false;
}

/** End copied GL utility methods */

bool checkGlError(JNIEnv* env) {
    int error;
    if ((error = glGetError()) != GL_NO_ERROR) {
        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                "GLES20 error: 0x%d", error);
        return true;
    }
    return false;
}

/**
 * Asynchronous low-overhead GL performance measurement using
 * http://www.khronos.org/registry/gles/extensions/EXT/EXT_disjoint_timer_query.txt
 *
 * Measures the duration of GPU processing for a set of GL commands, delivering
 * the measurement asynchronously once processing completes.
 *
 * All calls must come from a single thread with a valid GL context active.
 **/
class PerfMeasurementContext {
  private:
    Vector<GLuint> mTimingQueries;
    size_t mTimingStartIndex;
    size_t mTimingEndIndex;
    size_t mTimingQueryIndex;
    size_t mFreeQueries;

    bool mInitDone;
  public:

    /**
     * maxQueryCount should be a conservative estimate of how many query objects
     * will be active at once, which is a function of the GPU's level of
     * pipelining and the frequency of queries.
     */
    explicit PerfMeasurementContext(size_t maxQueryCount):
            mTimingStartIndex(0),
            mTimingEndIndex(0),
            mTimingQueryIndex(0) {
        mTimingQueries.resize(maxQueryCount);
        mFreeQueries = maxQueryCount;
        mInitDone = false;
    }

    int getMaxQueryCount() {
        return mTimingQueries.size();
    }

    /**
     * Start a measurement period using the next available query object.
     * Returns INVALID_OPERATION if called multiple times in a row,
     * and BAD_VALUE if no more query objects are available.
     */
    int startGlTimer() {
        // Lazy init of queries to avoid needing GL context during construction
        if (!mInitDone) {
            glGenQueriesEXT(mTimingQueries.size(), mTimingQueries.editArray());
            mInitDone = true;
        }

        if (mTimingEndIndex != mTimingStartIndex) {
            return INVALID_OPERATION;
        }

        if (mFreeQueries == 0) {
            return BAD_VALUE;
        }

        glBeginQueryEXT(GL_TIME_ELAPSED_EXT, mTimingQueries[mTimingStartIndex]);

        mTimingStartIndex = (mTimingStartIndex + 1) % mTimingQueries.size();
        mFreeQueries--;

        return OK;
    }

    /**
     * Finish the current measurement period
     * Returns INVALID_OPERATION if called before any startGLTimer calls
     * or if called multiple times in a row.
     */
    int stopGlTimer() {
        size_t nextEndIndex = (mTimingEndIndex + 1) % mTimingQueries.size();
        if (nextEndIndex != mTimingStartIndex) {
            return INVALID_OPERATION;
        }
        glEndQueryEXT(GL_TIME_ELAPSED_EXT);

        mTimingEndIndex = nextEndIndex;

        return OK;
    }

    static const nsecs_t NO_DURATION_YET = -1L;
    static const nsecs_t FAILED_MEASUREMENT = -2L;

    /**
     * Get the next available duration measurement.
     *
     * Returns NO_DURATION_YET if no new measurement is available,
     * and FAILED_MEASUREMENT if an error occurred during the next
     * measurement period.
     *
     * Otherwise returns a positive number of nanoseconds measuring the
     * duration of the oldest completed query.
     */
    nsecs_t getNextGlDuration() {
        if (!mInitDone) {
            // No start/stop called yet
            return NO_DURATION_YET;
        }

        GLint available;
        glGetQueryObjectivEXT(mTimingQueries[mTimingQueryIndex],
                GL_QUERY_RESULT_AVAILABLE_EXT, &available);
        if (!available) {
            return NO_DURATION_YET;
        }

        GLint64 duration = FAILED_MEASUREMENT;
        GLint disjointOccurred;
        glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjointOccurred);

        if (!disjointOccurred) {
            glGetQueryObjecti64vEXT(mTimingQueries[mTimingQueryIndex],
                    GL_QUERY_RESULT_EXT,
                    &duration);
        }

        mTimingQueryIndex = (mTimingQueryIndex + 1) % mTimingQueries.size();
        mFreeQueries++;

        return static_cast<nsecs_t>(duration);
    }

    static bool isMeasurementSupported() {
        const GLubyte* extensions = glGetString(GL_EXTENSIONS);
        return checkForExtension(extensions,
                reinterpret_cast<const GLubyte*>("GL_EXT_disjoint_timer_query"));
    }

};

PerfMeasurementContext* getContext(jlong context) {
    return reinterpret_cast<PerfMeasurementContext*>(context);
}

extern "C" {

static jlong PerfMeasurement_nativeCreateContext(JNIEnv* env, jobject thiz,
        jint maxQueryCount) {
    PerfMeasurementContext *context = new PerfMeasurementContext(maxQueryCount);
    return reinterpret_cast<jlong>(context);
}

static void PerfMeasurement_nativeDeleteContext(JNIEnv* env, jobject thiz,
        jlong contextHandle) {
    PerfMeasurementContext *context = getContext(contextHandle);
    delete(context);
}

static jboolean PerfMeasurement_nativeQuerySupport(JNIEnv* env, jobject thiz) {
    bool supported = PerfMeasurementContext::isMeasurementSupported();
    checkGlError(env);
    return static_cast<jboolean>(supported);
}

static void PerfMeasurement_nativeStartGlTimer(JNIEnv* env, jobject thiz,
        jlong contextHandle) {

    PerfMeasurementContext *context = getContext(contextHandle);
    status_t err = context->startGlTimer();
    if (err != OK) {
        switch (err) {
            case INVALID_OPERATION:
                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                        "Mismatched start/end GL timing calls");
                return;
            case BAD_VALUE:
                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                        "Too many timing queries in progress, max %d",
                        context->getMaxQueryCount());
                return;
            default:
                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                        "Unknown error starting GL timing");
                return;
        }
    }
    checkGlError(env);
}

static void PerfMeasurement_nativeStopGlTimer(JNIEnv* env, jobject thiz,
            jlong contextHandle) {

    PerfMeasurementContext *context = getContext(contextHandle);
    status_t err = context->stopGlTimer();
    if (err != OK) {
        switch (err) {
            case INVALID_OPERATION:
                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                        "Mismatched start/end GL timing calls");
                return;
            default:
                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                        "Unknown error ending GL timing");
                return;
        }
    }
    checkGlError(env);
}

static jlong PerfMeasurement_nativeGetNextGlDuration(JNIEnv* env,
        jobject thiz, jlong contextHandle) {
    PerfMeasurementContext *context = getContext(contextHandle);
    nsecs_t duration = context->getNextGlDuration();

    checkGlError(env);
    return static_cast<jlong>(duration);
}

} // extern "C"

static const JNINativeMethod gPerfMeasurementMethods[] = {
    { "nativeCreateContext",
      "(I)J",
      (jlong *)PerfMeasurement_nativeCreateContext },
    { "nativeDeleteContext",
      "(J)V",
      (void *)PerfMeasurement_nativeDeleteContext },
    { "nativeQuerySupport",
      "()Z",
      (jboolean *)PerfMeasurement_nativeQuerySupport },
    { "nativeStartGlTimer",
      "(J)V",
      (void *)PerfMeasurement_nativeStartGlTimer },
    { "nativeStopGlTimer",
      "(J)V",
      (void *)PerfMeasurement_nativeStopGlTimer },
    { "nativeGetNextGlDuration",
      "(J)J",
      (jlong *)PerfMeasurement_nativeGetNextGlDuration }
};


// Get all the required offsets in java class and register native functions
int register_android_hardware_camera2_legacy_PerfMeasurement(JNIEnv* env)
{
    // Register native functions
    return RegisterMethodsOrDie(env,
            PERF_MEASUREMENT_CLASS_NAME,
            gPerfMeasurementMethods,
            NELEM(gPerfMeasurementMethods));
}
