Skip to content

Commit

Permalink
[Remoting Android] GlDisplay with JniGlDisplayHandler outline
Browse files Browse the repository at this point in the history
This CL implements a GlDisplay Java class that is bridged with the native
JniGlDisplayHandler class. This class is used for the future GlDesktopView
to talk to the native OpenGL renderer. JniGlDisplayHandler will be filled
up after the actual rendering component is checked in.

This is part of the project of implementing OpenGL ES rendering on Android
and iOS.

BUG=385924

Review-Url: https://codereview.chromium.org/2115753003
Cr-Commit-Position: refs/heads/master@{#404365}
  • Loading branch information
ywh233 authored and Commit bot committed Jul 8, 2016
1 parent 485959b commit 4e161cc
Show file tree
Hide file tree
Showing 7 changed files with 317 additions and 21 deletions.
1 change: 1 addition & 0 deletions remoting/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ generate_jni("jni_headers") {
"host/src/org/chromium/chromoting/host/jni/Host.java",
"java/src/org/chromium/chromoting/jni/Client.java",
"java/src/org/chromium/chromoting/jni/Display.java",
"java/src/org/chromium/chromoting/jni/GlDisplay.java",
"java/src/org/chromium/chromoting/jni/JniInterface.java",
"java/src/org/chromium/chromoting/jni/TouchEventData.java",
]
Expand Down
1 change: 1 addition & 0 deletions remoting/android/client_java_tmpl.gni
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ template("remoting_android_client_java_tmpl") {
"jni/Client.java",
"jni/ConnectionListener.java",
"jni/Display.java",
"jni/GlDisplay.java",
"jni/JniInterface.java",
"jni/TouchEventData.java",
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,6 @@ private Display(long nativeDisplayHandler) {
mNativeJniDisplayHandler = nativeDisplayHandler;
}

/**
* @return the pointer to the native C++ object.
*/
public long getNativePointer() {
return mNativeJniDisplayHandler;
}

/**
* Sets the redraw callback to the provided functor. Provide a value of null whenever the
* window is no longer visible so that we don't continue to draw onto it. Called on the UI
Expand Down
177 changes: 177 additions & 0 deletions remoting/android/java/src/org/chromium/chromoting/jni/GlDisplay.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chromoting.jni;

import android.view.Surface;

import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.chromoting.Event;
import org.chromium.chromoting.SizeChangedEventParameter;

/**
* This class is the JNI interface class that helps bridging GlDesktopView with the OpenGL renderer
* in native code. The lifetime of this class is managed by the native JniGlDisplayHandler.
*
* This class works entirely on the UI thread:
* Functions should all be called on UI.
* Events will only be triggered on UI.
*/
@JNINamespace("remoting")
public class GlDisplay {
private volatile long mNativeJniGlDisplay;
private final Event.Raisable<SizeChangedEventParameter> mOnHostSizeChanged =
new Event.Raisable<>();
private final Event.Raisable<Void> mOnCanvasRendered =
new Event.Raisable<>();

private GlDisplay(long nativeJniGlDisplay) {
mNativeJniGlDisplay = nativeJniGlDisplay;
}

/**
* Invalidates this object and disconnects from the native display handler. Called on the
* display thread by the native code.
*/
@CalledByNative
private void invalidate() {
mNativeJniGlDisplay = 0;
}

/**
* Notifies the OpenGL renderer that a surface for OpenGL to draw is created.
* @param surface the surface to be drawn on
*/
public void surfaceCreated(Surface surface) {
if (mNativeJniGlDisplay != 0) {
nativeOnSurfaceCreated(mNativeJniGlDisplay, surface);
}
}

/**
* Notifies the OpenGL renderer the size of the surface. Should be called after surfaceCreated()
* and before surfaceDestroyed().
* @param width the width of the surface
* @param height the height of the surface
*/
public void surfaceChanged(int width, int height) {
if (mNativeJniGlDisplay != 0) {
nativeOnSurfaceChanged(mNativeJniGlDisplay, width, height);
}
}

/**
* Notifies the OpenGL renderer that the current surface being used is about to be destroyed.
*/
public void surfaceDestroyed() {
if (mNativeJniGlDisplay != 0) {
nativeOnSurfaceDestroyed(mNativeJniGlDisplay);
}
}

/**
* Sets the transformation matrix (in pixel coordinates).
* @param matrix the transformation matrix
*/
public void pixelTransformationChanged(float[] matrix) {
if (mNativeJniGlDisplay != 0) {
nativeOnPixelTransformationChanged(mNativeJniGlDisplay, matrix);
}
}

/**
* Moves the cursor to the corresponding location on the desktop.
*/
public void cursorPixelPositionChanged(int x, int y) {
if (mNativeJniGlDisplay != 0) {
nativeOnCursorPixelPositionChanged(mNativeJniGlDisplay, x, y);
}
}

/**
* Decides whether the cursor should be shown on the canvas.
*/
public void cursorVisibilityChanged(boolean visible) {
if (mNativeJniGlDisplay != 0) {
nativeOnCursorVisibilityChanged(mNativeJniGlDisplay, visible);
}
}

/**
* Called by native code to notify GlDisplay that the size of the canvas (=size of desktop) has
* changed.
* @param width width of the canvas
* @param height height of the canvas
*/
@CalledByNative
private void changeCanvasSize(int width, int height) {
mOnHostSizeChanged.raise(new SizeChangedEventParameter(width, height));
}

/**
* An {@link Event} triggered when the size of the host desktop is changed.
*/
public Event<SizeChangedEventParameter> onHostSizeChanged() {
return mOnHostSizeChanged;
}

/**
* Called by native code when a render request has been done by the OpenGL renderer. This
* will only be called when the render event callback is enabled.
*/
@CalledByNative
private void canvasRendered() {
mOnCanvasRendered.raise(null);
}

/**
* An {@link} triggered when render event callback is enabled and a render request has been done
* by the OpenGL renderer.
*/
public Event<Void> onCanvasRendered() {
return mOnCanvasRendered;
}

/**
* Enables or disables render event callback. {@link GlDisplay#onCanvasRendered()} will only be
* triggered if this is set to true.
* @param enabled true to enable and false to disable
*/
public void setRenderEventEnabled(boolean enabled) {
if (mNativeJniGlDisplay != 0) {
nativeSetRenderEventEnabled(mNativeJniGlDisplay, enabled);
}
}

/**
* Shows the cursor input feedback animation with the given diameter at the given desktop
* location.
*/
public void showCursorInputFeedback(int x, int y, float diameter) {
if (mNativeJniGlDisplay != 0) {
nativeOnCursorInputFeedback(mNativeJniGlDisplay, x, y, diameter);
}
}

@CalledByNative
private static GlDisplay createJavaDisplayObject(long nativeDisplayHandler) {
return new GlDisplay(nativeDisplayHandler);
}

private native void nativeOnSurfaceCreated(long nativeJniGlDisplayHandler, Surface surface);
private native void nativeOnSurfaceChanged(long nativeJniGlDisplayHandler,
int width, int height);
private native void nativeOnSurfaceDestroyed(long nativeJniGlDisplayHandler);
private native void nativeOnPixelTransformationChanged(long nativeJniGlDisplayHandler,
float[] matrix);
private native void nativeOnCursorPixelPositionChanged(long nativeJniGlDisplayHandler,
int x, int y);
private native void nativeOnCursorInputFeedback(long nativeJniGlDisplayHandler,
int x, int y, float diameter);
private native void nativeOnCursorVisibilityChanged(long nativeJniGlDisplayHandler,
boolean visible);
private native void nativeSetRenderEventEnabled(long nativeJniGlDisplayHandler,
boolean enabled);
}
3 changes: 2 additions & 1 deletion remoting/client/jni/jni_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "remoting/client/jni/chromoting_jni_runtime.h"
#include "remoting/client/jni/display_updater_factory.h"
#include "remoting/client/jni/jni_display_handler.h"
#include "remoting/client/jni/jni_gl_display_handler.h"
#include "remoting/client/jni/jni_pairing_secret_fetcher.h"
#include "remoting/client/jni/jni_touch_event_data.h"
#include "remoting/client/jni/jni_video_renderer.h"
Expand Down Expand Up @@ -161,7 +162,7 @@ void JniClient::Connect(
const base::android::JavaParamRef<jstring>& capabilities,
const base::android::JavaParamRef<jstring>& flags) {
#if defined(REMOTING_ANDROID_ENABLE_OPENGL_RENDERER)
#error Feature not implemented.
JniGlDisplayHandler* raw_display_handler = new JniGlDisplayHandler(runtime_);
#else
JniDisplayHandler* raw_display_handler = new JniDisplayHandler(runtime_);
#endif // defined(REMOTING_ANDROID_ENABLE_OPENGL_RENDERER)
Expand Down
90 changes: 83 additions & 7 deletions remoting/client/jni/jni_gl_display_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,28 @@
#include "remoting/client/jni/jni_gl_display_handler.h"

#include "base/logging.h"
#include "jni/GlDisplay_jni.h"
#include "remoting/client/jni/chromoting_jni_runtime.h"
#include "remoting/client/jni/jni_video_renderer.h"
#include "remoting/protocol/video_renderer.h"

namespace remoting {

JniGlDisplayHandler::JniGlDisplayHandler() {}
JniGlDisplayHandler::JniGlDisplayHandler(ChromotingJniRuntime* runtime) :
runtime_(runtime) {
java_display_.Reset(Java_GlDisplay_createJavaDisplayObject(
base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this)));
}

JniGlDisplayHandler::~JniGlDisplayHandler() {}
JniGlDisplayHandler::~JniGlDisplayHandler() {
DCHECK(runtime_->display_task_runner()->BelongsToCurrentThread());
Java_GlDisplay_invalidate(base::android::AttachCurrentThread(),
java_display_.obj());
}

base::android::ScopedJavaLocalRef<jobject>
JniGlDisplayHandler::GetJavaDisplay() {
return base::android::ScopedJavaLocalRef<jobject>(java_display_);
}

std::unique_ptr<protocol::CursorShapeStub>
JniGlDisplayHandler::CreateCursorShapeStub() {
Expand All @@ -28,13 +42,14 @@ JniGlDisplayHandler::CreateVideoRenderer() {

// static
bool JniGlDisplayHandler::RegisterJni(JNIEnv* env) {
NOTIMPLEMENTED();
return false;
return RegisterNativesImpl(env);
}

void JniGlDisplayHandler::OnSurfaceCreated(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& caller) {
const base::android::JavaParamRef<jobject>& caller,
const base::android::JavaParamRef<jobject>& surface) {
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
NOTIMPLEMENTED();
}

Expand All @@ -43,13 +58,74 @@ void JniGlDisplayHandler::OnSurfaceChanged(
const base::android::JavaParamRef<jobject>& caller,
int width,
int height) {
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
NOTIMPLEMENTED();
}

void JniGlDisplayHandler::OnDrawFrame(
void JniGlDisplayHandler::OnSurfaceDestroyed(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& caller) {
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
NOTIMPLEMENTED();
}

void JniGlDisplayHandler::OnPixelTransformationChanged(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& caller,
const base::android::JavaParamRef<jfloatArray>& jmatrix) {
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
NOTIMPLEMENTED();
}

void JniGlDisplayHandler::OnCursorPixelPositionChanged(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& caller,
int x,
int y) {
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
NOTIMPLEMENTED();
}

void JniGlDisplayHandler::OnCursorVisibilityChanged(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& caller,
bool visible) {
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
NOTIMPLEMENTED();
}

void JniGlDisplayHandler::OnCursorInputFeedback(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& caller,
int x,
int y,
float diameter) {
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
NOTIMPLEMENTED();
}

void JniGlDisplayHandler::SetRenderEventEnabled(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& caller,
jboolean enabled) {
DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
NOTIMPLEMENTED();
}

// static
void JniGlDisplayHandler::NotifyRenderEventOnUiThread(
base::android::ScopedJavaGlobalRef<jobject> java_client) {
Java_GlDisplay_canvasRendered(base::android::AttachCurrentThread(),
java_client.obj());
}

// static
void JniGlDisplayHandler::ChangeCanvasSizeOnUiThread(
base::android::ScopedJavaGlobalRef<jobject> java_client,
int width,
int height) {
JNIEnv* env = base::android::AttachCurrentThread();
Java_GlDisplay_changeCanvasSize(env, java_client.obj(), width, height);
}

} // namespace remoting
Loading

0 comments on commit 4e161cc

Please sign in to comment.