1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
// Copyright (c) 2013 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.
#ifndef ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_
#define ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_
#include "android_webview/browser/shared_renderer_state.h"
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
#include "base/cancelable_callback.h"
#include "content/public/browser/android/synchronous_compositor_client.h"
#include "skia/ext/refptr.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/vector2d_f.h"
class SkCanvas;
class SkPicture;
struct AwDrawGLInfo;
struct AwDrawSWFunctionTable;
namespace content {
class ContentViewCore;
class SynchronousCompositor;
class WebContents;
}
namespace android_webview {
class BrowserViewRendererClient;
// Delegate to perform rendering actions involving Java objects.
class BrowserViewRendererJavaHelper {
public:
static BrowserViewRendererJavaHelper* GetInstance();
typedef base::Callback<bool(SkCanvas*)> RenderMethod;
// Try obtaining the native SkCanvas from |java_canvas| and call
// |render_source| with it. If that fails, allocate an auxilary bitmap
// for |render_source| to render into, then copy the bitmap into
// |java_canvas|.
virtual bool RenderViaAuxilaryBitmapIfNeeded(
jobject java_canvas,
const gfx::Vector2d& scroll_correction,
const gfx::Rect& clip,
RenderMethod render_source) = 0;
protected:
virtual ~BrowserViewRendererJavaHelper() {}
};
// Interface for all the WebView-specific content rendering operations.
// Provides software and hardware rendering and the Capture Picture API.
class BrowserViewRenderer : public content::SynchronousCompositorClient {
public:
BrowserViewRenderer(BrowserViewRendererClient* client,
SharedRendererState* shared_renderer_state,
content::WebContents* web_contents);
virtual ~BrowserViewRenderer();
// Main handler for view drawing: performs a SW draw immediately, or sets up
// a subsequent GL Draw (via BrowserViewRendererClient::RequestDrawGL) and
// returns true. A false return value indicates nothing was or will be drawn.
// |java_canvas| is the target of the draw. |is_hardware_canvas| indicates
// a GL Draw maybe possible on this canvas. |scroll| if the view's current
// scroll offset. |clip| is the canvas's clip bounds. |global_visible_rect|
// is the intersection of the view size and the window in window coordinates.
bool OnDraw(jobject java_canvas,
bool is_hardware_canvas,
const gfx::Vector2d& scroll,
const gfx::Rect& global_visible_rect,
const gfx::Rect& clip);
void DidDrawGL(const DrawGLResult& result);
// CapturePicture API methods.
skia::RefPtr<SkPicture> CapturePicture(int width, int height);
void EnableOnNewPicture(bool enabled);
void ClearView();
// View update notifications.
void SetIsPaused(bool paused);
void SetViewVisibility(bool visible);
void SetWindowVisibility(bool visible);
void OnSizeChanged(int width, int height);
void OnAttachedToWindow(int width, int height);
void OnDetachedFromWindow();
// Sets the scale for logical<->physical pixel conversions.
void SetDipScale(float dip_scale);
// Set the root layer scroll offset to |new_value|.
void ScrollTo(gfx::Vector2d new_value);
// Android views hierarchy gluing.
bool IsAttachedToWindow() const;
bool IsVisible() const;
gfx::Rect GetScreenRect() const;
// Force invoke the compositor to run produce a 1x1 software frame that is
// immediately discarded. This is a hack to force invoke parts of the
// compositor that are not directly exposed here.
void ForceFakeCompositeSW();
// SynchronousCompositorClient overrides
virtual void DidInitializeCompositor(
content::SynchronousCompositor* compositor) OVERRIDE;
virtual void DidDestroyCompositor(content::SynchronousCompositor* compositor)
OVERRIDE;
virtual void SetContinuousInvalidate(bool invalidate) OVERRIDE;
virtual void SetMaxRootLayerScrollOffset(gfx::Vector2dF new_value) OVERRIDE;
virtual void SetTotalRootLayerScrollOffset(gfx::Vector2dF new_value_css)
OVERRIDE;
virtual void DidUpdateContent() OVERRIDE;
virtual gfx::Vector2dF GetTotalRootLayerScrollOffset() OVERRIDE;
virtual bool IsExternalFlingActive() const OVERRIDE;
virtual void SetRootLayerPageScaleFactorAndLimits(float page_scale_factor,
float min_page_scale_factor,
float max_page_scale_factor)
OVERRIDE;
virtual void SetRootLayerScrollableSize(gfx::SizeF scrollable_size) OVERRIDE;
virtual void DidOverscroll(gfx::Vector2dF accumulated_overscroll,
gfx::Vector2dF latest_overscroll_delta,
gfx::Vector2dF current_fling_velocity) OVERRIDE;
private:
// Checks the continuous invalidate and block invalidate state, and schedule
// invalidates appropriately. If |force_invalidate| is true, then send a view
// invalidate regardless of compositor expectation.
void EnsureContinuousInvalidation(bool force_invalidate);
bool DrawSWInternal(jobject java_canvas, const gfx::Rect& clip_bounds);
bool CompositeSW(SkCanvas* canvas);
void DidComposite(bool force_invalidate);
// If we call up view invalidate and OnDraw is not called before a deadline,
// then we keep ticking the SynchronousCompositor so it can make progress.
void FallbackTickFired();
gfx::Vector2d max_scroll_offset() const;
// For debug tracing or logging. Return the string representation of this
// view renderer's state and the |draw_info| if provided.
std::string ToString(AwDrawGLInfo* draw_info) const;
BrowserViewRendererClient* client_;
SharedRendererState* shared_renderer_state_;
content::WebContents* web_contents_;
bool has_compositor_;
bool is_paused_;
bool view_visible_;
bool window_visible_; // Only applicable if |attached_to_window_| is true.
bool attached_to_window_;
float dip_scale_;
float page_scale_factor_;
bool on_new_picture_enable_;
bool clear_view_;
// When true, we should continuously invalidate and keep drawing, for example
// to drive animation. This value is set by the compositor and should always
// reflect the expectation of the compositor and not be reused for other
// states.
bool compositor_needs_continuous_invalidate_;
// Used to block additional invalidates while one is already pending.
bool block_invalidates_;
// Holds a callback to FallbackTickFired while it is pending.
base::CancelableClosure fallback_tick_;
int width_;
int height_;
DrawGLInput draw_gl_input_;
// Current scroll offset in CSS pixels.
gfx::Vector2dF scroll_offset_dip_;
// Max scroll offset in CSS pixels.
gfx::Vector2dF max_scroll_offset_dip_;
// Used to prevent rounding errors from accumulating enough to generate
// visible skew (especially noticeable when scrolling up and down in the same
// spot over a period of time).
gfx::Vector2dF overscroll_rounding_error_;
DISALLOW_COPY_AND_ASSIGN(BrowserViewRenderer);
};
} // namespace android_webview
#endif // ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_
|