1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/browser/android/content_view_render_view.h" 6 7 #include "base/android/jni_android.h" 8 #include "base/android/jni_string.h" 9 #include "base/android/scoped_java_ref.h" 10 #include "base/bind.h" 11 #include "base/lazy_instance.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/message_loop/message_loop.h" 14 #include "cc/layers/layer.h" 15 #include "content/browser/android/content_view_core_impl.h" 16 #include "content/public/browser/android/compositor.h" 17 #include "content/public/browser/android/content_view_layer_renderer.h" 18 #include "jni/ContentViewRenderView_jni.h" 19 #include "ui/gfx/android/java_bitmap.h" 20 #include "ui/gfx/size.h" 21 22 #include <android/bitmap.h> 23 #include <android/native_window_jni.h> 24 25 using base::android::ScopedJavaLocalRef; 26 27 namespace content { 28 29 // static 30 bool ContentViewRenderView::RegisterContentViewRenderView(JNIEnv* env) { 31 return RegisterNativesImpl(env); 32 } 33 34 ContentViewRenderView::ContentViewRenderView(JNIEnv* env, 35 jobject obj, 36 gfx::NativeWindow root_window) 37 : buffers_swapped_during_composite_(false), 38 root_window_(root_window) { 39 java_obj_.Reset(env, obj); 40 } 41 42 ContentViewRenderView::~ContentViewRenderView() { 43 } 44 45 // static 46 static jlong Init(JNIEnv* env, jobject obj, jlong native_root_window) { 47 gfx::NativeWindow root_window = 48 reinterpret_cast<gfx::NativeWindow>(native_root_window); 49 ContentViewRenderView* content_view_render_view = 50 new ContentViewRenderView(env, obj, root_window); 51 return reinterpret_cast<intptr_t>(content_view_render_view); 52 } 53 54 void ContentViewRenderView::Destroy(JNIEnv* env, jobject obj) { 55 delete this; 56 } 57 58 void ContentViewRenderView::SetCurrentContentView( 59 JNIEnv* env, jobject obj, int native_content_view) { 60 InitCompositor(); 61 ContentViewCoreImpl* content_view = 62 reinterpret_cast<ContentViewCoreImpl*>(native_content_view); 63 if (content_view) 64 compositor_->SetRootLayer(content_view->GetLayer()); 65 else 66 compositor_->SetRootLayer(cc::Layer::Create()); 67 } 68 69 void ContentViewRenderView::SurfaceCreated( 70 JNIEnv* env, jobject obj, jobject jsurface) { 71 InitCompositor(); 72 compositor_->SetSurface(jsurface); 73 } 74 75 void ContentViewRenderView::SurfaceDestroyed(JNIEnv* env, jobject obj) { 76 compositor_->SetSurface(NULL); 77 } 78 79 void ContentViewRenderView::SurfaceSetSize( 80 JNIEnv* env, jobject obj, jint width, jint height) { 81 compositor_->SetWindowBounds(gfx::Size(width, height)); 82 } 83 84 jboolean ContentViewRenderView::Composite(JNIEnv* env, jobject obj) { 85 if (!compositor_) 86 return false; 87 88 buffers_swapped_during_composite_ = false; 89 compositor_->Composite(); 90 return buffers_swapped_during_composite_; 91 } 92 93 jboolean ContentViewRenderView::CompositeToBitmap(JNIEnv* env, jobject obj, 94 jobject java_bitmap) { 95 gfx::JavaBitmap bitmap(java_bitmap); 96 if (!compositor_ || bitmap.format() != ANDROID_BITMAP_FORMAT_RGBA_8888) 97 return false; 98 return compositor_->CompositeAndReadback(bitmap.pixels(), 99 gfx::Rect(bitmap.size())); 100 } 101 102 void ContentViewRenderView::ScheduleComposite() { 103 JNIEnv* env = base::android::AttachCurrentThread(); 104 Java_ContentViewRenderView_requestRender(env, java_obj_.obj()); 105 } 106 107 void ContentViewRenderView::OnSwapBuffersPosted() { 108 buffers_swapped_during_composite_ = true; 109 } 110 111 void ContentViewRenderView::OnSwapBuffersCompleted() { 112 JNIEnv* env = base::android::AttachCurrentThread(); 113 Java_ContentViewRenderView_onSwapBuffersCompleted(env, java_obj_.obj()); 114 } 115 116 void ContentViewRenderView::InitCompositor() { 117 if (!compositor_) 118 compositor_.reset(Compositor::Create(this, root_window_)); 119 } 120 121 } // namespace content 122