Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 001dd0cb authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Refactor GLES20Canvas/HardwareRenderer JNI layers"

parents b2a331ea 244ada1d
Loading
Loading
Loading
Loading
+0 −43
Original line number Diff line number Diff line
@@ -214,49 +214,6 @@ class GLES20Canvas extends HardwareCanvas {
    
    private static native void nSetViewport(int renderer, int width, int height);

    /**
     * Preserves the back buffer of the current surface after a buffer swap.
     * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current
     * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL
     * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
     * 
     * @return True if the swap behavior was successfully changed,
     *         false otherwise.
     * 
     * @hide
     */
    public static boolean preserveBackBuffer() {
        return nPreserveBackBuffer();
    }

    private static native boolean nPreserveBackBuffer();    

    /**
     * Indicates whether the current surface preserves its back buffer
     * after a buffer swap.
     * 
     * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED,
     *         false otherwise
     *         
     * @hide
     */
    public static boolean isBackBufferPreserved() {
        return nIsBackBufferPreserved();
    }

    private static native boolean nIsBackBufferPreserved();

    /**
     * Disables v-sync. For performance testing only.
     * 
     * @hide
     */
    public static void disableVsync() {
        nDisableVsync();
    }

    private static native void nDisableVsync();

    @Override
    public void onPreDraw(Rect dirty) {
        if (dirty != null) {
+42 −6
Original line number Diff line number Diff line
@@ -281,6 +281,43 @@ public abstract class HardwareRenderer {

    private static native void nBeginFrame();

    /**
     * Preserves the back buffer of the current surface after a buffer swap.
     * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current
     * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL
     * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
     *
     * @return True if the swap behavior was successfully changed,
     *         false otherwise.
     */
    static boolean preserveBackBuffer() {
        return nPreserveBackBuffer();
    }

    private static native boolean nPreserveBackBuffer();

    /**
     * Indicates whether the current surface preserves its back buffer
     * after a buffer swap.
     *
     * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED,
     *         false otherwise
     */
    static boolean isBackBufferPreserved() {
        return nIsBackBufferPreserved();
    }

    private static native boolean nIsBackBufferPreserved();

    /**
     * Disables v-sync. For performance testing only.
     */
    static void disableVsync() {
        nDisableVsync();
    }

    private static native void nDisableVsync();

    /**
     * Interface used to receive callbacks whenever a view is drawn by
     * a hardware renderer instance.
@@ -777,7 +814,7 @@ public abstract class HardwareRenderer {
            // If mDirtyRegions is set, this means we have an EGL configuration
            // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
            if (sDirtyRegions) {
                if (!(mDirtyRegionsEnabled = GLES20Canvas.preserveBackBuffer())) {
                if (!(mDirtyRegionsEnabled = preserveBackBuffer())) {
                    Log.w(LOG_TAG, "Backbuffer cannot be preserved");
                }
            } else if (sDirtyRegionsRequested) {
@@ -787,7 +824,7 @@ public abstract class HardwareRenderer {
                // want to set mDirtyRegions. We try to do this only if dirty
                // regions were initially requested as part of the device
                // configuration (see RENDER_DIRTY_REGIONS)
                mDirtyRegionsEnabled = GLES20Canvas.isBackBufferPreserved();
                mDirtyRegionsEnabled = isBackBufferPreserved();
            }
        }

@@ -926,7 +963,6 @@ public abstract class HardwareRenderer {
                    }

                    beginFrame();

                    onPreDraw(dirty);

                    HardwareCanvas canvas = mCanvas;
@@ -1203,7 +1239,7 @@ public abstract class HardwareRenderer {
        void setup(int width, int height) {
            super.setup(width, height);
            if (mVsyncDisabled) {
                GLES20Canvas.disableVsync();
                disableVsync();
            }
        }

+5 −52
Original line number Diff line number Diff line
@@ -62,9 +62,9 @@ using namespace uirenderer;
 */
#ifdef USE_OPENGL_RENDERER

///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// Defines
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------

// Debug
#define DEBUG_RENDERER 0
@@ -87,52 +87,9 @@ static struct {
} gRectClassInfo;

// ----------------------------------------------------------------------------
// Misc
// Caching
// ----------------------------------------------------------------------------

static jboolean android_view_GLES20Canvas_preserveBackBuffer(JNIEnv* env, jobject clazz) {
    EGLDisplay display = eglGetCurrentDisplay();
    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);

    eglGetError();
    eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);

    EGLint error = eglGetError();
    if (error != EGL_SUCCESS) {
        RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error);
    }

    return error == EGL_SUCCESS;
}

static jboolean android_view_GLES20Canvas_isBackBufferPreserved(JNIEnv* env, jobject clazz) {
    EGLDisplay display = eglGetCurrentDisplay();
    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
    EGLint value;

    eglGetError();
    eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &value);

    EGLint error = eglGetError();
    if (error != EGL_SUCCESS) {
        RENDERER_LOGD("Could not query buffer preserved swap behavior (%x)", error);
    }

    return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED;
}

static void android_view_GLES20Canvas_disableVsync(JNIEnv* env, jobject clazz) {
    EGLDisplay display = eglGetCurrentDisplay();

    eglGetError();
    eglSwapInterval(display, 0);

    EGLint error = eglGetError();
    if (error != EGL_SUCCESS) {
        RENDERER_LOGD("Could not disable v-sync (%x)", error);
    }
}

static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz,
        Caches::FlushMode mode) {
    if (Caches::hasInstance()) {
@@ -853,9 +810,6 @@ static JNINativeMethod gMethods[] = {
    { "nIsAvailable",       "()Z",             (void*) android_view_GLES20Canvas_isAvailable },

#ifdef USE_OPENGL_RENDERER
    { "nIsBackBufferPreserved", "()Z",         (void*) android_view_GLES20Canvas_isBackBufferPreserved },
    { "nPreserveBackBuffer",    "()Z",         (void*) android_view_GLES20Canvas_preserveBackBuffer },
    { "nDisableVsync",          "()V",         (void*) android_view_GLES20Canvas_disableVsync },
    { "nFlushCaches",           "(I)V",        (void*) android_view_GLES20Canvas_flushCaches },
    { "nInitCaches",            "()V",         (void*) android_view_GLES20Canvas_initCaches },
    { "nTerminateCaches",       "()V",         (void*) android_view_GLES20Canvas_terminateCaches },
@@ -869,8 +823,7 @@ static JNINativeMethod gMethods[] = {

    { "nGetStencilSize",    "()I",             (void*) android_view_GLES20Canvas_getStencilSize },

    { "nCallDrawGLFunction", "(II)I",
            (void*) android_view_GLES20Canvas_callDrawGLFunction },
    { "nCallDrawGLFunction", "(II)I",          (void*) android_view_GLES20Canvas_callDrawGLFunction },

    { "nSave",              "(II)I",           (void*) android_view_GLES20Canvas_save },
    { "nRestore",           "(I)V",            (void*) android_view_GLES20Canvas_restore },
+96 −11
Original line number Diff line number Diff line
@@ -20,30 +20,105 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>

#ifdef USE_OPENGL_RENDERER
    #include <EGL/egl_cache.h>

    EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
#endif

namespace android {

/**
 * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
 *       devices. This means all the logic must be compiled only when the
 *       preprocessor variable USE_OPENGL_RENDERER is defined.
 */
#ifdef USE_OPENGL_RENDERER

// ----------------------------------------------------------------------------
// Misc
// Defines
// ----------------------------------------------------------------------------

static void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
        jstring diskCachePath) {
// Debug
#define DEBUG_RENDERER 0

    const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
    egl_cache_t::get()->setCacheFilename(cacheArray);
    env->ReleaseStringUTFChars(diskCachePath, cacheArray);
// Debug
#if DEBUG_RENDERER
    #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__)
#else
    #define RENDERER_LOGD(...)
#endif

// ----------------------------------------------------------------------------
// Surface and display management
// ----------------------------------------------------------------------------

static jboolean android_view_HardwareRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) {
    EGLDisplay display = eglGetCurrentDisplay();
    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);

    eglGetError();
    eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);

    EGLint error = eglGetError();
    if (error != EGL_SUCCESS) {
        RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error);
    }

    return error == EGL_SUCCESS;
}

static jboolean android_view_HardwareRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) {
    EGLDisplay display = eglGetCurrentDisplay();
    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
    EGLint value;

    eglGetError();
    eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &value);

    EGLint error = eglGetError();
    if (error != EGL_SUCCESS) {
        RENDERER_LOGD("Could not query buffer preserved swap behavior (%x)", error);
    }

    return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED;
}

static void android_view_HardwareRenderer_disableVsync(JNIEnv* env, jobject clazz) {
    EGLDisplay display = eglGetCurrentDisplay();

    eglGetError();
    eglSwapInterval(display, 0);

    EGLint error = eglGetError();
    if (error != EGL_SUCCESS) {
        RENDERER_LOGD("Could not disable v-sync (%x)", error);
    }
}

// ----------------------------------------------------------------------------
// Tracing and debugging
// ----------------------------------------------------------------------------

static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz) {
    EGLDisplay dpy = eglGetCurrentDisplay();
    EGLSurface surf = eglGetCurrentSurface(EGL_DRAW);
    eglBeginFrame(dpy, surf);
}

#endif // USE_OPENGL_RENDERER

// ----------------------------------------------------------------------------
// Shaders
// ----------------------------------------------------------------------------

static void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
        jstring diskCachePath) {

    const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
    egl_cache_t::get()->setCacheFilename(cacheArray);
    env->ReleaseStringUTFChars(diskCachePath, cacheArray);
}

// ----------------------------------------------------------------------------
// JNI Glue
// ----------------------------------------------------------------------------
@@ -51,10 +126,20 @@ static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz)
const char* const kClassPathName = "android/view/HardwareRenderer";

static JNINativeMethod gMethods[] = {
    { "nSetupShadersDiskCache", "(Ljava/lang/String;)V",
            (void*) android_view_HardwareRenderer_setupShadersDiskCache },
#ifdef USE_OPENGL_RENDERER
    { "nIsBackBufferPreserved", "()Z",
            (void*) android_view_HardwareRenderer_isBackBufferPreserved },
    { "nPreserveBackBuffer",    "()Z",
            (void*) android_view_HardwareRenderer_preserveBackBuffer },
    { "nDisableVsync",          "()V",
            (void*) android_view_HardwareRenderer_disableVsync },

    { "nBeginFrame", "()V",
            (void*) android_view_HardwareRenderer_beginFrame },
#endif

    { "nSetupShadersDiskCache", "(Ljava/lang/String;)V",
            (void*) android_view_HardwareRenderer_setupShadersDiskCache },
};

int register_android_view_HardwareRenderer(JNIEnv* env) {