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

package android.hardware.camera2.legacy;

import android.os.SystemClock;
import android.util.Log;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

/**
 * GPU and CPU performance measurement for the legacy implementation.
 *
 * <p>Measures CPU and GPU processing duration for a set of operations, and dumps
 * the results into a file.</p>
 *
 * <p>Rough usage:
 * <pre>
 * {@code
 *   <set up workload>
 *   <start long-running workload>
 *   mPerfMeasurement.startTimer();
 *   ...render a frame...
 *   mPerfMeasurement.stopTimer();
 *   <end workload>
 *   mPerfMeasurement.dumpPerformanceData("/sdcard/my_data.txt");
 * }
 * </pre>
 * </p>
 *
 * <p>All calls to this object must be made within the same thread, and the same GL context.
 * PerfMeasurement cannot be used outside of a GL context.  The only exception is
 * dumpPerformanceData, which can be called outside of a valid GL context.</p>
 */
class PerfMeasurement {
    private static final String TAG = "PerfMeasurement";

    public static final int DEFAULT_MAX_QUERIES = 3;

    private final long mNativeContext;

    private int mCompletedQueryCount = 0;

    /**
     * Values for completed measurements
     */
    private ArrayList<Long> mCollectedGpuDurations = new ArrayList<>();
    private ArrayList<Long> mCollectedCpuDurations = new ArrayList<>();
    private ArrayList<Long> mCollectedTimestamps = new ArrayList<>();

    /**
     * Values for in-progress measurements (waiting for async GPU results)
     */
    private Queue<Long> mTimestampQueue = new LinkedList<>();
    private Queue<Long> mCpuDurationsQueue = new LinkedList<>();

    private long mStartTimeNs;

    /**
     * The value returned by {@link #nativeGetNextGlDuration} if no new timing
     * measurement is available since the last call.
     */
    private static final long NO_DURATION_YET = -1l;

    /**
     * The value returned by {@link #nativeGetNextGlDuration} if timing failed for
     * the next timing interval
     */
    private static final long FAILED_TIMING = -2l;

    /**
     * Create a performance measurement object with a maximum of {@value #DEFAULT_MAX_QUERIES}
     * in-progess queries.
     */
    public PerfMeasurement() {
        mNativeContext = nativeCreateContext(DEFAULT_MAX_QUERIES);
    }

    /**
     * Create a performance measurement object with maxQueries as the maximum number of
     * in-progress queries.
     *
     * @param maxQueries maximum in-progress queries, must be larger than 0.
     * @throws IllegalArgumentException if maxQueries is less than 1.
     */
    public PerfMeasurement(int maxQueries) {
        if (maxQueries < 1) throw new IllegalArgumentException("maxQueries is less than 1");
        mNativeContext = nativeCreateContext(maxQueries);
    }

    /**
     * Returns true if the Gl timing methods will work, false otherwise.
     *
     * <p>Must be called within a valid GL context.</p>
     */
    public static boolean isGlTimingSupported() {
        return nativeQuerySupport();
    }

    /**
     * Dump collected data to file, and clear the stored data.
     *
     * <p>
     * Format is a simple csv-like text file with a header,
     * followed by a 3-column list of values in nanoseconds:
     * <pre>
     *   timestamp gpu_duration cpu_duration
     *   <long> <long> <long>
     *   <long> <long> <long>
     *   <long> <long> <long>
     *   ....
     * </pre>
     * </p>
     */
    public void dumpPerformanceData(String path) {
        try (BufferedWriter dump = new BufferedWriter(new FileWriter(path))) {
            dump.write("timestamp gpu_duration cpu_duration\n");
            for (int i = 0; i < mCollectedGpuDurations.size(); i++) {
                dump.write(String.format("%d %d %d\n",
                                mCollectedTimestamps.get(i),
                                mCollectedGpuDurations.get(i),
                                mCollectedCpuDurations.get(i)));
            }
            mCollectedTimestamps.clear();
            mCollectedGpuDurations.clear();
            mCollectedCpuDurations.clear();
        } catch (IOException e) {
            Log.e(TAG, "Error writing data dump to " + path + ":" + e);
        }
    }

    /**
     * Start a GPU/CPU timing measurement.
     *
     * <p>Call before starting a rendering pass. Only one timing measurement can be active at once,
     * so {@link #stopTimer} must be called before the next call to this method.</p>
     *
     * @throws IllegalStateException if the maximum number of queries are in progress already,
     *                               or the method is called multiple times in a row, or there is
     *                               a GPU error.
     */
    public void startTimer() {
        nativeStartGlTimer(mNativeContext);
        mStartTimeNs = SystemClock.elapsedRealtimeNanos();
    }

    /**
     * Finish a GPU/CPU timing measurement.
     *
     * <p>Call after finishing all the drawing for a rendering pass. Only one timing measurement can
     * be active at once, so {@link #startTimer} must be called before the next call to this
     * method.</p>
     *
     * @throws IllegalStateException if no GL timer is currently started, or there is a GPU
     *                               error.
     */
    public void stopTimer() {
        // Complete CPU timing
        long endTimeNs = SystemClock.elapsedRealtimeNanos();
        mCpuDurationsQueue.add(endTimeNs - mStartTimeNs);
        // Complete GL timing
        nativeStopGlTimer(mNativeContext);

        // Poll to see if GL timing results have arrived; if so
        // store the results for a frame
        long duration = getNextGlDuration();
        if (duration > 0) {
            mCollectedGpuDurations.add(duration);
            mCollectedTimestamps.add(mTimestampQueue.isEmpty() ?
                    NO_DURATION_YET : mTimestampQueue.poll());
            mCollectedCpuDurations.add(mCpuDurationsQueue.isEmpty() ?
                    NO_DURATION_YET : mCpuDurationsQueue.poll());
        }
        if (duration == FAILED_TIMING) {
            // Discard timestamp and CPU measurement since GPU measurement failed
            if (!mTimestampQueue.isEmpty()) {
                mTimestampQueue.poll();
            }
            if (!mCpuDurationsQueue.isEmpty()) {
                mCpuDurationsQueue.poll();
            }
        }
    }

    /**
     * Add a timestamp to a timing measurement. These are queued up and matched to completed
     * workload measurements as they become available.
     */
    public void addTimestamp(long timestamp) {
        mTimestampQueue.add(timestamp);
    }

    /**
     * Get the next available GPU timing measurement.
     *
     * <p>Since the GPU works asynchronously, the results of a single start/stopGlTimer measurement
     * will only be available some time after the {@link #stopTimer} call is made. Poll this method
     * until the result becomes available. If multiple start/endTimer measurements are made in a
     * row, the results will be available in FIFO order.</p>
     *
     * @return The measured duration of the GPU workload for the next pending query, or
     *         {@link #NO_DURATION_YET} if no queries are pending or the next pending query has not
     *         yet finished, or {@link #FAILED_TIMING} if the GPU was unable to complete the
     *         measurement.
     *
     * @throws IllegalStateException If there is a GPU error.
     *
     */
    private long getNextGlDuration() {
        long duration = nativeGetNextGlDuration(mNativeContext);
        if (duration > 0) {
            mCompletedQueryCount++;
        }
        return duration;
    }

    /**
     * Returns the number of measurements so far that returned a valid duration
     * measurement.
     */
    public int getCompletedQueryCount() {
        return mCompletedQueryCount;
    }

    @Override
    protected void finalize() {
        nativeDeleteContext(mNativeContext);
    }

    /**
     * Create a native performance measurement context.
     *
     * @param maxQueryCount maximum in-progress queries; must be >= 1.
     */
    private static native long nativeCreateContext(int maxQueryCount);

    /**
     * Delete the native context.
     *
     * <p>Not safe to call more than once.</p>
     */
    private static native void nativeDeleteContext(long contextHandle);

    /**
     * Query whether the relevant Gl extensions are available for Gl timing
     */
    private static native boolean nativeQuerySupport();

    /**
     * Start a GL timing section.
     *
     * <p>All GL commands between this method and the next {@link #nativeEndGlTimer} will be
     * included in the timing.</p>
     *
     * <p>Must be called from the same thread as calls to {@link #nativeEndGlTimer} and
     * {@link #nativeGetNextGlDuration}.</p>
     *
     * @throws IllegalStateException if a GL error occurs or start is called repeatedly.
     */
    protected static native void nativeStartGlTimer(long contextHandle);

    /**
     * Finish a GL timing section.
     *
     * <p>Some time after this call returns, the time the GPU took to
     * execute all work submitted between the latest {@link #nativeStartGlTimer} and
     * this call, will become available from calling {@link #nativeGetNextGlDuration}.</p>
     *
     * <p>Must be called from the same thread as calls to {@link #nativeStartGlTimer} and
     * {@link #nativeGetNextGlDuration}.</p>
     *
     * @throws IllegalStateException if a GL error occurs or stop is called before start
     */
    protected static native void nativeStopGlTimer(long contextHandle);

    /**
     * Get the next available GL duration measurement, in nanoseconds.
     *
     * <p>Must be called from the same thread as calls to {@link #nativeStartGlTimer} and
     * {@link #nativeEndGlTimer}.</p>
     *
     * @return the next GL duration measurement, or {@link #NO_DURATION_YET} if
     *         no new measurement is available, or {@link #FAILED_TIMING} if timing
     *         failed for the next duration measurement.
     * @throws IllegalStateException if a GL error occurs
     */
    protected static native long nativeGetNextGlDuration(long contextHandle);


}
