1 // Copyright 2019 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 "components/thin_webview/internal/compositor_view_impl.h"
6
7 #include <android/native_window_jni.h>
8
9 #include <memory>
10
11 #include "base/android/jni_android.h"
12 #include "cc/layers/solid_color_layer.h"
13 #include "components/thin_webview/internal/jni_headers/CompositorViewImpl_jni.h"
14 #include "content/public/browser/android/compositor.h"
15 #include "third_party/skia/include/core/SkColor.h"
16 #include "ui/android/window_android.h"
17
18 using base::android::JavaParamRef;
19 using base::android::JavaRef;
20
21 namespace thin_webview {
22 namespace android {
23 namespace {
24 const int kPixelFormatUnknown = 0;
25 } // namespace
26
JNI_CompositorViewImpl_Init(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobject> & jwindow_android,jint java_background_color)27 jlong JNI_CompositorViewImpl_Init(JNIEnv* env,
28 const JavaParamRef<jobject>& obj,
29 const JavaParamRef<jobject>& jwindow_android,
30 jint java_background_color) {
31 ui::WindowAndroid* window_android =
32 ui::WindowAndroid::FromJavaWindowAndroid(jwindow_android);
33 auto compositor_view = std::make_unique<CompositorViewImpl>(
34 env, obj, window_android, java_background_color);
35 return reinterpret_cast<intptr_t>(compositor_view.release());
36 }
37
38 // static
FromJavaObject(const base::android::JavaRef<jobject> & jcompositor_view)39 CompositorView* CompositorView::FromJavaObject(
40 const base::android::JavaRef<jobject>& jcompositor_view) {
41 if (jcompositor_view.is_null())
42 return nullptr;
43
44 return reinterpret_cast<CompositorViewImpl*>(
45 Java_CompositorViewImpl_getNativePtr(base::android::AttachCurrentThread(),
46 jcompositor_view));
47 }
48
CompositorViewImpl(JNIEnv * env,jobject obj,ui::WindowAndroid * window_android,int64_t java_background_color)49 CompositorViewImpl::CompositorViewImpl(JNIEnv* env,
50 jobject obj,
51 ui::WindowAndroid* window_android,
52 int64_t java_background_color)
53 : obj_(env, obj),
54 root_layer_(cc::SolidColorLayer::Create()),
55 current_surface_format_(kPixelFormatUnknown) {
56 compositor_.reset(content::Compositor::Create(this, window_android));
57 root_layer_->SetIsDrawable(true);
58 root_layer_->SetBackgroundColor(static_cast<SkColor>(java_background_color));
59 }
60
61 CompositorViewImpl::~CompositorViewImpl() = default;
62
Destroy(JNIEnv * env,const JavaParamRef<jobject> & object)63 void CompositorViewImpl::Destroy(JNIEnv* env,
64 const JavaParamRef<jobject>& object) {
65 delete this;
66 }
67
SurfaceCreated(JNIEnv * env,const JavaParamRef<jobject> & object)68 void CompositorViewImpl::SurfaceCreated(JNIEnv* env,
69 const JavaParamRef<jobject>& object) {
70 compositor_->SetRootLayer(root_layer_);
71 current_surface_format_ = kPixelFormatUnknown;
72 }
73
SurfaceDestroyed(JNIEnv * env,const JavaParamRef<jobject> & object)74 void CompositorViewImpl::SurfaceDestroyed(JNIEnv* env,
75 const JavaParamRef<jobject>& object) {
76 compositor_->SetSurface(nullptr, false);
77 current_surface_format_ = kPixelFormatUnknown;
78 }
79
SurfaceChanged(JNIEnv * env,const JavaParamRef<jobject> & object,jint format,jint width,jint height,bool can_be_used_with_surface_control,const JavaParamRef<jobject> & surface)80 void CompositorViewImpl::SurfaceChanged(JNIEnv* env,
81 const JavaParamRef<jobject>& object,
82 jint format,
83 jint width,
84 jint height,
85 bool can_be_used_with_surface_control,
86 const JavaParamRef<jobject>& surface) {
87 DCHECK(surface);
88 if (current_surface_format_ != format) {
89 current_surface_format_ = format;
90 compositor_->SetSurface(surface, can_be_used_with_surface_control);
91 }
92
93 gfx::Size content_size(width, height);
94 compositor_->SetWindowBounds(content_size);
95 root_layer_->SetBounds(content_size);
96 }
97
SetNeedsComposite(JNIEnv * env,const JavaParamRef<jobject> & object)98 void CompositorViewImpl::SetNeedsComposite(
99 JNIEnv* env,
100 const JavaParamRef<jobject>& object) {
101 compositor_->SetNeedsComposite();
102 }
103
SetRootLayer(scoped_refptr<cc::Layer> layer)104 void CompositorViewImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) {
105 const cc::LayerList& children = root_layer_->children();
106 DCHECK(children.size() <= 1);
107 if (!children.empty() && children[0]->id() == layer->id())
108 return;
109
110 root_layer_->RemoveAllChildren();
111 root_layer_->InsertChild(layer, 0);
112 }
113
RecreateSurface()114 void CompositorViewImpl::RecreateSurface() {
115 JNIEnv* env = base::android::AttachCurrentThread();
116 compositor_->SetSurface(nullptr, false);
117 Java_CompositorViewImpl_recreateSurface(env, obj_);
118 }
119
UpdateLayerTreeHost()120 void CompositorViewImpl::UpdateLayerTreeHost() {
121 JNIEnv* env = base::android::AttachCurrentThread();
122 Java_CompositorViewImpl_onCompositorLayout(env, obj_);
123 }
124
125 } // namespace android
126 } // namespace thin_webview
127