summaryrefslogtreecommitdiffstats
path: root/remoting/client/jni
diff options
context:
space:
mode:
authorsergeyu <sergeyu@chromium.org>2015-08-19 19:02:18 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-20 02:02:56 +0000
commit13bca69cfa261ec8eb6bffecf59c486b683eb8db (patch)
tree2a6c5c5217c4e148ff4c2e94c0e48a2cc2997014 /remoting/client/jni
parent7a402ba51bf75c883cde14c8bd83fa082f685c08 (diff)
downloadchromium_src-13bca69cfa261ec8eb6bffecf59c486b683eb8db.zip
chromium_src-13bca69cfa261ec8eb6bffecf59c486b683eb8db.tar.gz
chromium_src-13bca69cfa261ec8eb6bffecf59c486b683eb8db.tar.bz2
remoting: Simplify FrameConsumer interface and remove FrameProducer interface.
Now FrameConsumer implementation is responsible for scaling. This makes interaction with FrameConsumer much simpler. Also removed FrameProducer interface as it's no longer needed. Currently video scaling is only used in the plugin when Graphics3D is not available. In that case Graphics2D::SetScale() performs better than trying to scale the image in the plugin, especially given that the scaling code is not optimized for PNaCl. This refactoring also allowed to simplify threading logic in the rendering both on Android and in the plugin. BUG=256850, 486917, 509914 Review URL: https://codereview.chromium.org/1288063004 Cr-Commit-Position: refs/heads/master@{#344404}
Diffstat (limited to 'remoting/client/jni')
-rw-r--r--remoting/client/jni/chromoting_jni_instance.cc72
-rw-r--r--remoting/client/jni/chromoting_jni_instance.h16
-rw-r--r--remoting/client/jni/chromoting_jni_runtime.cc5
-rw-r--r--remoting/client/jni/chromoting_jni_runtime.h3
-rw-r--r--remoting/client/jni/jni_frame_consumer.cc159
-rw-r--r--remoting/client/jni/jni_frame_consumer.h63
6 files changed, 112 insertions, 206 deletions
diff --git a/remoting/client/jni/chromoting_jni_instance.cc b/remoting/client/jni/chromoting_jni_instance.cc
index dc5c4d7..9c0fae7 100644
--- a/remoting/client/jni/chromoting_jni_instance.cc
+++ b/remoting/client/jni/chromoting_jni_instance.cc
@@ -15,6 +15,7 @@
#include "remoting/client/client_status_logger.h"
#include "remoting/client/jni/android_keymap.h"
#include "remoting/client/jni/chromoting_jni_runtime.h"
+#include "remoting/client/jni/jni_frame_consumer.h"
#include "remoting/client/software_video_renderer.h"
#include "remoting/client/token_fetcher_proxy.h"
#include "remoting/protocol/chromium_port_allocator.h"
@@ -85,10 +86,9 @@ ChromotingJniInstance::ChromotingJniInstance(ChromotingJniRuntime* jni_runtime,
token_fetcher.Pass(), auth_methods));
// Post a task to start connection
- jni_runtime_->display_task_runner()->PostTask(
+ jni_runtime_->network_task_runner()->PostTask(
FROM_HERE,
- base::Bind(&ChromotingJniInstance::ConnectToHostOnDisplayThread,
- this));
+ base::Bind(&ChromotingJniInstance::ConnectToHostOnNetworkThread, this));
}
ChromotingJniInstance::~ChromotingJniInstance() {
@@ -105,23 +105,25 @@ ChromotingJniInstance::~ChromotingJniInstance() {
}
void ChromotingJniInstance::Disconnect() {
- if (!jni_runtime_->display_task_runner()->BelongsToCurrentThread()) {
- jni_runtime_->display_task_runner()->PostTask(
+ if (!jni_runtime_->network_task_runner()->BelongsToCurrentThread()) {
+ jni_runtime_->network_task_runner()->PostTask(
FROM_HERE,
base::Bind(&ChromotingJniInstance::Disconnect, this));
return;
}
- // This must be destroyed on the display thread before the producer is gone.
- view_.reset();
+ host_id_.clear();
- // The weak pointers must be invalidated on the same thread they were used.
- view_weak_factory_->InvalidateWeakPtrs();
+ stats_logging_enabled_ = false;
- jni_runtime_->network_task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ChromotingJniInstance::DisconnectFromHostOnNetworkThread,
- this));
+ // |client_| must be torn down before |signaling_|.
+ client_.reset();
+ client_status_logger_.reset();
+ video_renderer_.reset();
+ view_.reset();
+ authenticator_.reset();
+ signaling_.reset();
+ client_context_.reset();
}
void ChromotingJniInstance::FetchThirdPartyToken(
@@ -381,36 +383,17 @@ void ChromotingJniInstance::SetCursorShape(
jni_runtime_->UpdateCursorShape(shape);
}
-void ChromotingJniInstance::ConnectToHostOnDisplayThread() {
- DCHECK(jni_runtime_->display_task_runner()->BelongsToCurrentThread());
-
- view_.reset(new JniFrameConsumer(jni_runtime_, this));
- view_weak_factory_.reset(new base::WeakPtrFactory<JniFrameConsumer>(
- view_.get()));
- scoped_ptr<FrameConsumerProxy> frame_consumer =
- make_scoped_ptr(new FrameConsumerProxy(view_weak_factory_->GetWeakPtr()));
-
- jni_runtime_->network_task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ChromotingJniInstance::ConnectToHostOnNetworkThread, this,
- base::Passed(&frame_consumer)));
-}
-
-void ChromotingJniInstance::ConnectToHostOnNetworkThread(
- scoped_ptr<FrameConsumerProxy> frame_consumer) {
+void ChromotingJniInstance::ConnectToHostOnNetworkThread() {
DCHECK(jni_runtime_->network_task_runner()->BelongsToCurrentThread());
- DCHECK(frame_consumer);
jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
client_context_.reset(new ClientContext(jni_runtime_->network_task_runner()));
client_context_->Start();
- SoftwareVideoRenderer* renderer = new SoftwareVideoRenderer(
- client_context_->main_task_runner(),
- client_context_->decode_task_runner(), frame_consumer.Pass());
- view_->set_frame_producer(renderer);
- video_renderer_.reset(renderer);
+ view_.reset(new JniFrameConsumer(jni_runtime_));
+ video_renderer_.reset(new SoftwareVideoRenderer(
+ client_context_->decode_task_runner(), view_.get()));
client_.reset(new ChromotingClient(
client_context_.get(), this, video_renderer_.get(), nullptr));
@@ -441,22 +424,6 @@ void ChromotingJniInstance::ConnectToHostOnNetworkThread(
transport_factory.Pass(), host_jid_, capabilities_);
}
-void ChromotingJniInstance::DisconnectFromHostOnNetworkThread() {
- DCHECK(jni_runtime_->network_task_runner()->BelongsToCurrentThread());
-
- host_id_.clear();
-
- stats_logging_enabled_ = false;
-
- // |client_| must be torn down before |signaling_|.
- client_.reset();
- client_status_logger_.reset();
- video_renderer_.reset();
- authenticator_.reset();
- signaling_.reset();
- client_context_.reset();
-}
-
void ChromotingJniInstance::FetchSecret(
bool pairable,
const protocol::SecretFetchedCallback& callback) {
@@ -494,7 +461,6 @@ void ChromotingJniInstance::SendKeyEventInternal(int usb_key_code,
return;
}
-
protocol::KeyEvent event;
event.set_usb_keycode(usb_key_code);
event.set_pressed(key_down);
diff --git a/remoting/client/jni/chromoting_jni_instance.h b/remoting/client/jni/chromoting_jni_instance.h
index 2ce50e0..5511fef 100644
--- a/remoting/client/jni/chromoting_jni_instance.h
+++ b/remoting/client/jni/chromoting_jni_instance.h
@@ -14,8 +14,6 @@
#include "remoting/client/chromoting_client.h"
#include "remoting/client/client_context.h"
#include "remoting/client/client_user_interface.h"
-#include "remoting/client/frame_consumer_proxy.h"
-#include "remoting/client/jni/jni_frame_consumer.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/cursor_shape_stub.h"
#include "remoting/signaling/xmpp_signal_strategy.h"
@@ -27,9 +25,11 @@ class ClipboardEvent;
class CursorShapeInfo;
} // namespace protocol
+class ChromotingJniRuntime;
class ClientStatusLogger;
-class VideoRenderer;
+class JniFrameConsumer;
class TokenFetcherProxy;
+class VideoRenderer;
// ClientUserInterface that indirectly makes and receives JNI calls.
class ChromotingJniInstance
@@ -118,10 +118,7 @@ class ChromotingJniInstance
// This object is ref-counted, so it cleans itself up.
~ChromotingJniInstance() override;
- void ConnectToHostOnDisplayThread();
- void ConnectToHostOnNetworkThread(
- scoped_ptr<FrameConsumerProxy> frame_consumer);
- void DisconnectFromHostOnNetworkThread();
+ void ConnectToHostOnNetworkThread();
// Notifies the user interface that the user needs to enter a PIN. The
// current authentication attempt is put on hold until |callback| is invoked.
@@ -150,12 +147,9 @@ class ChromotingJniInstance
std::string host_id_;
std::string host_jid_;
- // This group of variables is to be used on the display thread.
- scoped_ptr<JniFrameConsumer> view_;
- scoped_ptr<base::WeakPtrFactory<JniFrameConsumer>> view_weak_factory_;
-
// This group of variables is to be used on the network thread.
scoped_ptr<ClientContext> client_context_;
+ scoped_ptr<JniFrameConsumer> view_;
scoped_ptr<VideoRenderer> video_renderer_;
scoped_ptr<protocol::Authenticator> authenticator_;
scoped_ptr<ChromotingClient> client_;
diff --git a/remoting/client/jni/chromoting_jni_runtime.cc b/remoting/client/jni/chromoting_jni_runtime.cc
index cb7dbb0..18884a0 100644
--- a/remoting/client/jni/chromoting_jni_runtime.cc
+++ b/remoting/client/jni/chromoting_jni_runtime.cc
@@ -18,7 +18,6 @@
#include "jni/JniInterface_jni.h"
#include "media/base/yuv_convert.h"
#include "remoting/base/url_request_context_getter.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertUTF8ToJavaString;
@@ -324,9 +323,9 @@ void ChromotingJniRuntime::HandleExtensionMessage(const std::string& type,
}
base::android::ScopedJavaLocalRef<jobject> ChromotingJniRuntime::NewBitmap(
- webrtc::DesktopSize size) {
+ int width, int height) {
JNIEnv* env = base::android::AttachCurrentThread();
- return Java_JniInterface_newBitmap(env, size.width(), size.height());
+ return Java_JniInterface_newBitmap(env, width, height);
}
void ChromotingJniRuntime::UpdateFrameBitmap(jobject bitmap) {
diff --git a/remoting/client/jni/chromoting_jni_runtime.h b/remoting/client/jni/chromoting_jni_runtime.h
index 0d0ea5e..1ca1124 100644
--- a/remoting/client/jni/chromoting_jni_runtime.h
+++ b/remoting/client/jni/chromoting_jni_runtime.h
@@ -97,8 +97,7 @@ class ChromotingJniRuntime {
const std::string& message);
// Creates a new Bitmap object to store a video frame.
- base::android::ScopedJavaLocalRef<jobject> NewBitmap(
- webrtc::DesktopSize size);
+ base::android::ScopedJavaLocalRef<jobject> NewBitmap(int width, int height);
// Updates video frame bitmap. |bitmap| must be an instance of
// android.graphics.Bitmap. Call on the display thread.
diff --git a/remoting/client/jni/jni_frame_consumer.cc b/remoting/client/jni/jni_frame_consumer.cc
index d921bfb..8c84dba 100644
--- a/remoting/client/jni/jni_frame_consumer.cc
+++ b/remoting/client/jni/jni_frame_consumer.cc
@@ -5,11 +5,9 @@
#include "remoting/client/jni/jni_frame_consumer.h"
#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
#include "base/logging.h"
-#include "base/stl_util.h"
-#include "base/synchronization/waitable_event.h"
#include "remoting/base/util.h"
-#include "remoting/client/frame_producer.h"
#include "remoting/client/jni/chromoting_jni_instance.h"
#include "remoting/client/jni/chromoting_jni_runtime.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
@@ -18,47 +16,51 @@
namespace remoting {
-JniFrameConsumer::JniFrameConsumer(
- ChromotingJniRuntime* jni_runtime,
- scoped_refptr<ChromotingJniInstance> jni_instance)
- : jni_runtime_(jni_runtime),
- jni_instance_(jni_instance),
- frame_producer_(nullptr) {
-}
+class JniFrameConsumer::Renderer {
+ public:
+ Renderer(ChromotingJniRuntime* jni_runtime) : jni_runtime_(jni_runtime) {}
+ ~Renderer() {
+ DCHECK(jni_runtime_->display_task_runner()->BelongsToCurrentThread());
+ }
-JniFrameConsumer::~JniFrameConsumer() {
- // The producer should now return any pending buffers. At this point, however,
- // ReturnBuffer() tasks scheduled by the producer will not be delivered,
- // so we free all the buffers once the producer's queue is empty.
- base::WaitableEvent done_event(true, false);
- frame_producer_->RequestReturnBuffers(
- base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done_event)));
- done_event.Wait();
-
- STLDeleteElements(&buffers_);
-}
+ void RenderFrame(scoped_ptr<webrtc::DesktopFrame> frame);
-void JniFrameConsumer::set_frame_producer(FrameProducer* producer) {
- frame_producer_ = producer;
-}
+ private:
+ // Used to obtain task runner references and make calls to Java methods.
+ ChromotingJniRuntime* jni_runtime_;
+
+ // This global reference is required, instead of a local reference, so it
+ // remains valid for the lifetime of |bitmap_| - gfx::JavaBitmap does not
+ // create its own global reference internally. And this global ref must be
+ // destroyed (released) after |bitmap_| is destroyed.
+ base::android::ScopedJavaGlobalRef<jobject> bitmap_global_ref_;
-void JniFrameConsumer::ApplyBuffer(const webrtc::DesktopSize& view_size,
- const webrtc::DesktopRect& clip_area,
- webrtc::DesktopFrame* buffer,
- const webrtc::DesktopRegion& region,
- const webrtc::DesktopRegion* shape) {
+ // Reference to the frame bitmap that is passed to Java when the frame is
+ // allocated. This provides easy access to the underlying pixels.
+ scoped_ptr<gfx::JavaBitmap> bitmap_;
+};
+
+// Function called on the display thread to render the frame.
+void JniFrameConsumer::Renderer::RenderFrame(
+ scoped_ptr<webrtc::DesktopFrame> frame) {
DCHECK(jni_runtime_->display_task_runner()->BelongsToCurrentThread());
- DCHECK(!shape);
-
- if (bitmap_->size().width() != buffer->size().width() ||
- bitmap_->size().height() != buffer->size().height()) {
- // Drop the frame, since the data belongs to the previous generation,
- // before SetSourceSize() called SetOutputSizeAndClip().
- FreeBuffer(buffer);
- return;
+
+ if (!bitmap_ || bitmap_->size().width() != frame->size().width() ||
+ bitmap_->size().height() != frame->size().height()) {
+ // Allocate a new Bitmap, store references here, and pass it to Java.
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ // |bitmap_| must be deleted before |bitmap_global_ref_| is released.
+ bitmap_.reset();
+ bitmap_global_ref_.Reset(
+ env,
+ jni_runtime_->NewBitmap(frame->size().width(), frame->size().height())
+ .obj());
+ bitmap_.reset(new gfx::JavaBitmap(bitmap_global_ref_.obj()));
+ jni_runtime_->UpdateFrameBitmap(bitmap_global_ref_.obj());
}
- // Copy pixels from |buffer| into the Java Bitmap.
+ // Copy pixels from |frame| into the Java Bitmap.
// TODO(lambroslambrou): Optimize away this copy by having the VideoDecoder
// decode directly into the Bitmap's pixel memory. This currently doesn't
// work very well because the VideoDecoder writes the decoded data in BGRA,
@@ -66,70 +68,53 @@ void JniFrameConsumer::ApplyBuffer(const webrtc::DesktopSize& view_size,
// If a repaint is triggered from a Java event handler, the unswapped pixels
// can sometimes appear on the display.
uint8* dest_buffer = static_cast<uint8*>(bitmap_->pixels());
- webrtc::DesktopRect buffer_rect = webrtc::DesktopRect::MakeSize(view_size);
-
- for (webrtc::DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) {
- const webrtc::DesktopRect& rect(i.rect());
- CopyRGB32Rect(buffer->data(), buffer->stride(), buffer_rect, dest_buffer,
- bitmap_->stride(), buffer_rect, rect);
+ webrtc::DesktopRect buffer_rect =
+ webrtc::DesktopRect::MakeSize(frame->size());
+ for (webrtc::DesktopRegion::Iterator i(frame->updated_region()); !i.IsAtEnd();
+ i.Advance()) {
+ CopyRGB32Rect(frame->data(), frame->stride(), buffer_rect, dest_buffer,
+ bitmap_->stride(), buffer_rect, i.rect());
}
- // TODO(lambroslambrou): Optimize this by only repainting the changed pixels.
- base::TimeTicks start_time = base::TimeTicks::Now();
jni_runtime_->RedrawCanvas();
- jni_instance_->RecordPaintTime(
- (base::TimeTicks::Now() - start_time).InMilliseconds());
-
- // Supply |frame_producer_| with a buffer to render the next frame into.
- frame_producer_->DrawBuffer(buffer);
-}
-
-void JniFrameConsumer::ReturnBuffer(webrtc::DesktopFrame* buffer) {
- DCHECK(jni_runtime_->display_task_runner()->BelongsToCurrentThread());
- FreeBuffer(buffer);
}
-void JniFrameConsumer::SetSourceSize(const webrtc::DesktopSize& source_size,
- const webrtc::DesktopVector& dpi) {
- DCHECK(jni_runtime_->display_task_runner()->BelongsToCurrentThread());
-
- // We currently render the desktop 1:1 and perform pan/zoom scaling
- // and cropping on the managed canvas.
- clip_area_ = webrtc::DesktopRect::MakeSize(source_size);
- frame_producer_->SetOutputSizeAndClip(source_size, clip_area_);
+JniFrameConsumer::JniFrameConsumer(ChromotingJniRuntime* jni_runtime)
+ : jni_runtime_(jni_runtime),
+ renderer_(new Renderer(jni_runtime)),
+ weak_factory_(this) {}
- // Allocate buffer and start drawing frames onto it.
- AllocateBuffer(source_size);
+JniFrameConsumer::~JniFrameConsumer() {
+ jni_runtime_->display_task_runner()->DeleteSoon(FROM_HERE,
+ renderer_.release());
}
-FrameConsumer::PixelFormat JniFrameConsumer::GetPixelFormat() {
- return FORMAT_RGBA;
+scoped_ptr<webrtc::DesktopFrame> JniFrameConsumer::AllocateFrame(
+ const webrtc::DesktopSize& size) {
+ return make_scoped_ptr(new webrtc::BasicDesktopFrame(size));
}
-void JniFrameConsumer::AllocateBuffer(const webrtc::DesktopSize& source_size) {
- DCHECK(jni_runtime_->display_task_runner()->BelongsToCurrentThread());
-
- webrtc::DesktopSize size(source_size.width(), source_size.height());
+void JniFrameConsumer::DrawFrame(scoped_ptr<webrtc::DesktopFrame> frame,
+ const base::Closure& done) {
+ DCHECK(jni_runtime_->network_task_runner()->BelongsToCurrentThread());
- // Allocate a new Bitmap, store references here, and pass it to Java.
- JNIEnv* env = base::android::AttachCurrentThread();
+ jni_runtime_->display_task_runner()->PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(&Renderer::RenderFrame, base::Unretained(renderer_.get()),
+ base::Passed(&frame)),
+ base::Bind(&JniFrameConsumer::OnFrameRendered, weak_factory_.GetWeakPtr(),
+ done));
+}
- // |bitmap_| must be deleted before |bitmap_global_ref_| is released.
- bitmap_.reset();
- bitmap_global_ref_.Reset(env, jni_runtime_->NewBitmap(size).obj());
- bitmap_.reset(new gfx::JavaBitmap(bitmap_global_ref_.obj()));
- jni_runtime_->UpdateFrameBitmap(bitmap_global_ref_.obj());
+void JniFrameConsumer::OnFrameRendered(const base::Closure& done) {
+ DCHECK(jni_runtime_->network_task_runner()->BelongsToCurrentThread());
- webrtc::DesktopFrame* buffer = new webrtc::BasicDesktopFrame(size);
- buffers_.push_back(buffer);
- frame_producer_->DrawBuffer(buffer);
+ if (!done.is_null())
+ done.Run();
}
-void JniFrameConsumer::FreeBuffer(webrtc::DesktopFrame* buffer) {
- DCHECK(std::find(buffers_.begin(), buffers_.end(), buffer) != buffers_.end());
-
- buffers_.remove(buffer);
- delete buffer;
+FrameConsumer::PixelFormat JniFrameConsumer::GetPixelFormat() {
+ return FORMAT_RGBA;
}
} // namespace remoting
diff --git a/remoting/client/jni/jni_frame_consumer.h b/remoting/client/jni/jni_frame_consumer.h
index a9a0361..5a9f7e6 100644
--- a/remoting/client/jni/jni_frame_consumer.h
+++ b/remoting/client/jni/jni_frame_consumer.h
@@ -7,80 +7,43 @@
#include <list>
-#include "base/android/scoped_java_ref.h"
#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "remoting/client/frame_consumer.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
-namespace gfx {
-class JavaBitmap;
-} // namespace gfx
-
-namespace webrtc {
-class DesktopFrame;
-} // namespace webrtc
-
namespace remoting {
-class ChromotingJniInstance;
+
class ChromotingJniRuntime;
-class FrameProducer;
// FrameConsumer implementation that draws onto a JNI direct byte buffer.
class JniFrameConsumer : public FrameConsumer {
public:
- // The instance does not take ownership of |jni_runtime|.
- explicit JniFrameConsumer(ChromotingJniRuntime* jni_runtime,
- scoped_refptr<ChromotingJniInstance> jni_instance);
+ // Does not take ownership of |jni_runtime|.
+ explicit JniFrameConsumer(ChromotingJniRuntime* jni_runtime);
~JniFrameConsumer() override;
- // This must be called once before the producer's source size is set.
- void set_frame_producer(FrameProducer* producer);
-
// FrameConsumer implementation.
- void ApplyBuffer(const webrtc::DesktopSize& view_size,
- const webrtc::DesktopRect& clip_area,
- webrtc::DesktopFrame* buffer,
- const webrtc::DesktopRegion& region,
- const webrtc::DesktopRegion* shape) override;
- void ReturnBuffer(webrtc::DesktopFrame* buffer) override;
- void SetSourceSize(const webrtc::DesktopSize& source_size,
- const webrtc::DesktopVector& dpi) override;
+ scoped_ptr<webrtc::DesktopFrame> AllocateFrame(
+ const webrtc::DesktopSize& size) override;
+ void DrawFrame(scoped_ptr<webrtc::DesktopFrame> frame,
+ const base::Closure& done) override;
PixelFormat GetPixelFormat() override;
private:
- // Allocates a new buffer of |source_size|, informs Java about it, and tells
- // the producer to draw onto it.
- void AllocateBuffer(const webrtc::DesktopSize& source_size);
+ class Renderer;
- // Frees a frame buffer previously allocated by AllocateBuffer.
- void FreeBuffer(webrtc::DesktopFrame* buffer);
-
- // Variables are to be used from the display thread.
+ void OnFrameRendered(const base::Closure& done);
// Used to obtain task runner references and make calls to Java methods.
ChromotingJniRuntime* jni_runtime_;
- // Used to record statistics.
- scoped_refptr<ChromotingJniInstance> jni_instance_;
-
- FrameProducer* frame_producer_;
- webrtc::DesktopRect clip_area_;
-
- // List of allocated image buffers.
- std::list<webrtc::DesktopFrame*> buffers_;
-
- // This global reference is required, instead of a local reference, so it
- // remains valid for the lifetime of |bitmap_| - gfx::JavaBitmap does not
- // create its own global reference internally. And this global ref must be
- // destroyed (released) after |bitmap_| is destroyed.
- base::android::ScopedJavaGlobalRef<jobject> bitmap_global_ref_;
+ // Renderer object used to render the frames on the display thread.
+ scoped_ptr<Renderer> renderer_;
- // Reference to the frame bitmap that is passed to Java when the frame is
- // allocated. This provides easy access to the underlying pixels.
- scoped_ptr<gfx::JavaBitmap> bitmap_;
+ base::WeakPtrFactory<JniFrameConsumer> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(JniFrameConsumer);
};