Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java

Issue 2201483002: Improve transition between opaque and translucent compositor views. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: removed CompositorSurfaceView Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.compositor; 5 package org.chromium.chrome.browser.compositor;
6 6
7 import android.app.Activity; 7 import android.app.Activity;
8 import android.content.Context; 8 import android.content.Context;
9 import android.graphics.Color; 9 import android.graphics.Color;
10 import android.graphics.PixelFormat; 10 import android.graphics.PixelFormat;
11 import android.graphics.Rect; 11 import android.graphics.Rect;
12 import android.graphics.drawable.Drawable;
12 import android.os.Build; 13 import android.os.Build;
13 import android.view.Display; 14 import android.view.Display;
14 import android.view.MotionEvent; 15 import android.view.MotionEvent;
15 import android.view.Surface; 16 import android.view.Surface;
16 import android.view.SurfaceHolder; 17 import android.view.SurfaceHolder;
17 import android.view.SurfaceView; 18 import android.view.SurfaceView;
18 import android.view.View; 19 import android.view.View;
20 import android.view.ViewGroup;
19 import android.view.WindowManager; 21 import android.view.WindowManager;
22 import android.widget.FrameLayout;
20 23
21 import org.chromium.base.CommandLine; 24 import org.chromium.base.CommandLine;
22 import org.chromium.base.Log; 25 import org.chromium.base.Log;
23 import org.chromium.base.TraceEvent; 26 import org.chromium.base.TraceEvent;
24 import org.chromium.base.VisibleForTesting; 27 import org.chromium.base.VisibleForTesting;
25 import org.chromium.base.annotations.CalledByNative; 28 import org.chromium.base.annotations.CalledByNative;
26 import org.chromium.base.annotations.JNINamespace; 29 import org.chromium.base.annotations.JNINamespace;
27 import org.chromium.chrome.browser.ChromeSwitches; 30 import org.chromium.chrome.browser.ChromeSwitches;
28 import org.chromium.chrome.browser.compositor.layouts.Layout; 31 import org.chromium.chrome.browser.compositor.layouts.Layout;
29 import org.chromium.chrome.browser.compositor.layouts.LayoutProvider; 32 import org.chromium.chrome.browser.compositor.layouts.LayoutProvider;
(...skipping 10 matching lines...) Expand all
40 import org.chromium.ui.base.DeviceFormFactor; 43 import org.chromium.ui.base.DeviceFormFactor;
41 import org.chromium.ui.base.WindowAndroid; 44 import org.chromium.ui.base.WindowAndroid;
42 import org.chromium.ui.resources.AndroidResourceType; 45 import org.chromium.ui.resources.AndroidResourceType;
43 import org.chromium.ui.resources.ResourceManager; 46 import org.chromium.ui.resources.ResourceManager;
44 47
45 /** 48 /**
46 * The is the {@link View} displaying the ui compositor results; including webpa ges and tabswitcher. 49 * The is the {@link View} displaying the ui compositor results; including webpa ges and tabswitcher.
47 */ 50 */
48 @JNINamespace("android") 51 @JNINamespace("android")
49 public class CompositorView 52 public class CompositorView
50 extends SurfaceView implements ContentOffsetProvider, SurfaceHolder.Call back { 53 extends FrameLayout implements ContentOffsetProvider, SurfaceHolder.Call back {
51 private static final String TAG = "CompositorView"; 54 private static final String TAG = "CompositorView";
52 private static final long NANOSECONDS_PER_MILLISECOND = 1000000; 55 private static final long NANOSECONDS_PER_MILLISECOND = 1000000;
53 56
54 // Cache objects that should not be created every frame 57 // Cache objects that should not be created every frame
55 private final Rect mCacheViewport = new Rect(); 58 private final Rect mCacheViewport = new Rect();
56 private final Rect mCacheAppRect = new Rect(); 59 private final Rect mCacheAppRect = new Rect();
57 private final Rect mCacheVisibleViewport = new Rect(); 60 private final Rect mCacheVisibleViewport = new Rect();
58 private final int[] mCacheViewPosition = new int[2]; 61 private final int[] mCacheViewPosition = new int[2];
59 62
63 // If true, then we'll use one surface, and always make it translucent.
64 // This can have power implications unless the compositor is using a format
65 // that does not have an alpha channel for opaque rendering (e.g., 565), or
66 // if the hardware is optimized for it (e.g., some QC GPUs).
67 private boolean mAlwaysTranslucent;
68
69 // Set of SurfaceViews that we maintain.
70 // CompositorViewHolder might be a more natural place to maintain these,
71 // except that we own the compositor.
boliu 2016/10/12 23:33:34 I'd prefer to refactor the code first, and avoid y
liberato (no reviews please) 2016/11/14 22:12:34 i've refactored all of the new code out into a sep
72 private SurfaceView mForegroundSurfaceView;
boliu 2016/10/12 23:33:35 suggestion: webview had a similar pattern for full
liberato (no reviews please) 2016/11/14 22:12:34 yes, you're quite right. good catch. i've refact
73
74 // This will be null if |mAlwaysTranslucent|, since we never switch the
75 // pixel format in that case.
76 private SurfaceView mBackgroundSurfaceView;
77
78 // Are we waiting to hide mBackgroundSurfaceView until the foreground SV
79 // has something to display?
80 private boolean mHideBackgroundPending;
81
82 // How many frames remain until we hide the newly-swapped background?
83 private int mFramesUntilHide;
84
85 // Cache of setWillNotDraw, which we keep up to date if we switch SVs.
86 private boolean mWillNotDraw;
87
60 private long mNativeCompositorView; 88 private long mNativeCompositorView;
61 private final LayoutRenderHost mRenderHost; 89 private final LayoutRenderHost mRenderHost;
62 private boolean mEnableTabletTabStack; 90 private boolean mEnableTabletTabStack;
63 private int mPreviousWindowTop = -1; 91 private int mPreviousWindowTop = -1;
64 92
65 private int mLastLayerCount; 93 private int mLastLayerCount;
66 94
67 // A conservative estimate of when a frame is guaranteed to be presented aft er being submitted. 95 // A conservative estimate of when a frame is guaranteed to be presented aft er being submitted.
68 private long mFramePresentationDelay; 96 private long mFramePresentationDelay;
69 97
70 // Resource Management 98 // Resource Management
71 private ResourceManager mResourceManager; 99 private ResourceManager mResourceManager;
72 100
73 // Lazily populated as it is needed. 101 // Lazily populated as it is needed.
74 private View mRootActivityView; 102 private View mRootActivityView;
75 private WindowAndroid mWindowAndroid; 103 private WindowAndroid mWindowAndroid;
76 private LayerTitleCache mLayerTitleCache; 104 private LayerTitleCache mLayerTitleCache;
77 private TabContentManager mTabContentManager; 105 private TabContentManager mTabContentManager;
78 106
79 private View mRootView; 107 private View mRootView;
80 private int mSurfaceWidth; 108 private int mSurfaceWidth;
81 private int mSurfaceHeight; 109 private int mSurfaceHeight;
82 private boolean mPreloadedResources; 110 private boolean mPreloadedResources;
83 111
84 // The current SurfaceView pixel format. Defaults to OPAQUE. 112 // The pixel format that we've told the compositor about.
85 private int mCurrentPixelFormat = PixelFormat.OPAQUE; 113 private int mVirtualPixelFormat = PixelFormat.OPAQUE;
114
115 // The current SurfaceView pixel format. Defaults to OPAQUE. This will be
116 // the same as mVirtualPixelFormat unless we're mAlwaysTranslucent.
117 private int mActualPixelFormat = PixelFormat.OPAQUE;
86 118
87 /** 119 /**
88 * Creates a {@link CompositorView}. This can be called only after the nativ e library is 120 * Creates a {@link CompositorView}. This can be called only after the nativ e library is
89 * properly loaded. 121 * properly loaded.
90 * @param c The Context to create this {@link CompositorView} in. 122 * @param c The Context to create this {@link CompositorView} in.
91 * @param host The renderer host owning this view. 123 * @param host The renderer host owning this view.
92 */ 124 */
93 public CompositorView(Context c, LayoutRenderHost host) { 125 public CompositorView(Context c, LayoutRenderHost host) {
94 super(c); 126 super(c);
95 mRenderHost = host; 127 mRenderHost = host;
96 resetFlags(); 128 resetFlags();
129
130 mForegroundSurfaceView = createSurfaceView();
131 attachSurfaceView(mForegroundSurfaceView);
132
97 setVisibility(View.INVISIBLE); 133 setVisibility(View.INVISIBLE);
98 setZOrderMediaOverlay(true); 134 bringChildToFront(mForegroundSurfaceView);
99 } 135 }
100 136
101 /** 137 /**
102 * @param view The root view of the hierarchy. 138 * @param view The root view of the hierarchy.
103 */ 139 */
104 public void setRootView(View view) { 140 public void setRootView(View view) {
105 mRootView = view; 141 mRootView = view;
106 } 142 }
107 143
108 /** 144 /**
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 * @return The ResourceManager. 193 * @return The ResourceManager.
158 */ 194 */
159 public ResourceManager getResourceManager() { 195 public ResourceManager getResourceManager() {
160 return mResourceManager; 196 return mResourceManager;
161 } 197 }
162 198
163 /** 199 /**
164 * Should be called for cleanup when the CompositorView instance is no longe r used. 200 * Should be called for cleanup when the CompositorView instance is no longe r used.
165 */ 201 */
166 public void shutDown() { 202 public void shutDown() {
167 getHolder().removeCallback(this); 203 mForegroundSurfaceView.getHolder().removeCallback(this);
204 if (mBackgroundSurfaceView != null) mBackgroundSurfaceView.getHolder().r emoveCallback(this);
168 if (mNativeCompositorView != 0) nativeDestroy(mNativeCompositorView); 205 if (mNativeCompositorView != 0) nativeDestroy(mNativeCompositorView);
169 mNativeCompositorView = 0; 206 mNativeCompositorView = 0;
170 } 207 }
171 208
172 /** 209 /**
173 * Initializes the {@link CompositorView}'s native parts (e.g. the rendering parts). 210 * Initializes the {@link CompositorView}'s native parts (e.g. the rendering parts).
174 * @param lowMemDevice If this is a low memory device. 211 * @param lowMemDevice If this is a low memory device.
175 * @param windowAndroid A {@link WindowAndroid} instance. 212 * @param windowAndroid A {@link WindowAndroid} instance.
176 * @param layerTitleCache A {@link LayerTitleCache} instance. 213 * @param layerTitleCache A {@link LayerTitleCache} instance.
177 * @param tabContentManager A {@link TabContentManager} instance. 214 * @param tabContentManager A {@link TabContentManager} instance.
178 */ 215 */
179 public void initNativeCompositor(boolean lowMemDevice, WindowAndroid windowA ndroid, 216 public void initNativeCompositor(boolean lowMemDevice, WindowAndroid windowA ndroid,
180 LayerTitleCache layerTitleCache, TabContentManager tabContentManager ) { 217 LayerTitleCache layerTitleCache, TabContentManager tabContentManager ) {
181 mWindowAndroid = windowAndroid; 218 mWindowAndroid = windowAndroid;
182 mLayerTitleCache = layerTitleCache; 219 mLayerTitleCache = layerTitleCache;
183 mTabContentManager = tabContentManager; 220 mTabContentManager = tabContentManager;
184 221
222 // compositor_impl_android.cc will use 565 EGL surfaces if and only if
223 // we're using a low memory device, and no alpha channel is desired.
224 // Otherwise, it will use 8888. Since SurfaceFlinger doesn't need
225 // the eOpaque flag to optimize out alpha blending during composition if
226 // the buffer has no alpha channel, we can avoid using the extra
227 // background surface (and the memory it requires) in the low memory
228 // case. The output buffer will either have an alpha channel or not,
229 // depending on whether the compositor needs it.
230 // We can keep the surface translucent all the times without worrying
231 // about the impact on power usage during SurfaceFlinger composition.
232 // We might also want to set |mAlwaysTranslucent| on non-low memory
233 // devices , if we are running on hardware that implements efficient
234 // alpha blending.
235 mAlwaysTranslucent = lowMemDevice;
236 if (mAlwaysTranslucent) {
237 mActualPixelFormat = PixelFormat.TRANSLUCENT;
238 mForegroundSurfaceView.getHolder().setFormat(mActualPixelFormat);
239 } else {
240 // We will switch between background and foreground SurfaceViews.
241 mBackgroundSurfaceView = createSurfaceView();
242 }
243
185 mNativeCompositorView = nativeInit(lowMemDevice, 244 mNativeCompositorView = nativeInit(lowMemDevice,
186 windowAndroid.getNativePointer(), layerTitleCache, tabContentMan ager); 245 windowAndroid.getNativePointer(), layerTitleCache, tabContentMan ager);
187 246
188 assert !getHolder().getSurface().isValid() 247 assert !getHolder().getSurface().isValid()
189 : "Surface created before native library loaded."; 248 : "Surface created before native library loaded.";
190 getHolder().addCallback(this); 249 mForegroundSurfaceView.getHolder().addCallback(this);
250 if (mBackgroundSurfaceView != null) mBackgroundSurfaceView.getHolder().a ddCallback(this);
191 251
192 // Cover the black surface before it has valid content. 252 // Cover the black surface before it has valid content.
193 setBackgroundColor(Color.WHITE); 253 setBackgroundColor(Color.WHITE);
194 setVisibility(View.VISIBLE); 254 setVisibility(View.VISIBLE);
255 mForegroundSurfaceView.setVisibility(View.VISIBLE);
195 256
196 mFramePresentationDelay = 0; 257 mFramePresentationDelay = 0;
197 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { 258 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
198 Display display = 259 Display display =
199 ((WindowManager) getContext().getSystemService(Context.WINDO W_SERVICE)) 260 ((WindowManager) getContext().getSystemService(Context.WINDO W_SERVICE))
200 .getDefaultDisplay(); 261 .getDefaultDisplay();
201 long presentationDeadline = display.getPresentationDeadlineNanos() 262 long presentationDeadline = display.getPresentationDeadlineNanos()
202 / NANOSECONDS_PER_MILLISECOND; 263 / NANOSECONDS_PER_MILLISECOND;
203 long vsyncPeriod = mWindowAndroid.getVsyncPeriodInMillis(); 264 long vsyncPeriod = mWindowAndroid.getVsyncPeriodInMillis();
204 mFramePresentationDelay = Math.min(3 * vsyncPeriod, 265 mFramePresentationDelay = Math.min(3 * vsyncPeriod,
205 ((presentationDeadline + vsyncPeriod - 1) / vsyncPeriod) * v syncPeriod); 266 ((presentationDeadline + vsyncPeriod - 1) / vsyncPeriod) * v syncPeriod);
206 } 267 }
207 268
208 // Grab the Resource Manager 269 // Grab the Resource Manager
209 mResourceManager = nativeGetResourceManager(mNativeCompositorView); 270 mResourceManager = nativeGetResourceManager(mNativeCompositorView);
210 } 271 }
211 272
212 @Override 273 @Override
213 public boolean onTouchEvent(MotionEvent e) { 274 public boolean onTouchEvent(MotionEvent e) {
214 return super.onTouchEvent(e); 275 return super.onTouchEvent(e);
215 } 276 }
216 277
217 /** 278 /**
218 * Enables/disables overlay video mode. Affects alpha blending on this view. 279 * Enables/disables overlay video mode. Affects alpha blending on this view.
219 * @param enabled Whether to enter or leave overlay video mode. 280 * @param enabled Whether to enter or leave overlay video mode.
220 */ 281 */
221 public void setOverlayVideoMode(boolean enabled) { 282 public void setOverlayVideoMode(boolean enabled) {
222 mCurrentPixelFormat = enabled ? PixelFormat.TRANSLUCENT : PixelFormat.OP AQUE; 283 int oldFormat = mVirtualPixelFormat;
223 getHolder().setFormat(mCurrentPixelFormat); 284 mVirtualPixelFormat = enabled ? PixelFormat.TRANSLUCENT : PixelFormat.OP AQUE;
boliu 2016/10/12 23:33:34 would it be easier to just keep a boolean mOverlay
liberato (no reviews please) 2016/11/14 22:12:34 changed significantly due to the refactor.
224 nativeSetOverlayVideoMode(mNativeCompositorView, enabled); 285 if (mVirtualPixelFormat == oldFormat) return;
286
287 // Figure out what we want to tell the surface.
288 mActualPixelFormat = mAlwaysTranslucent ? PixelFormat.TRANSLUCENT : mVir tualPixelFormat;
289
290 if (!mForegroundSurfaceView.getHolder().getSurface().isValid()) {
291 // No current view -- just set the format on it. The compositor
292 // will get a surfaceCreated message later.
293 getHolder().setFormat(mActualPixelFormat);
294 nativeSetOverlayVideoMode(mNativeCompositorView, enabled);
295 return;
296 }
297
298 if (mAlwaysTranslucent) {
299 // Update the compositor by pretending that the surface changed. We
300 // don't need to update the actual pixel format, though.
301 nativeSurfaceDestroyed(mNativeCompositorView);
boliu 2016/10/12 23:33:34 is Destroy/Created needed here? previous code didn
liberato (no reviews please) 2016/11/14 22:12:34 it did, via the real surfaceCreated / Destroyed ca
302 nativeSetOverlayVideoMode(mNativeCompositorView, enabled);
303 nativeSurfaceCreated(mNativeCompositorView);
304 return;
305 }
306
307 // Update the actual pixel format by switching to the other SurfaceView.
308 // The rest of the transition will happen when the surface is ready.
309 mBackgroundSurfaceView.getHolder().setFormat(mActualPixelFormat);
310 attachSurfaceView(mBackgroundSurfaceView);
311 mBackgroundSurfaceView.setVisibility(View.VISIBLE);
312 requestLayout();
boliu 2016/10/12 23:33:35 is invalidate by itself not enough? also use post
liberato (no reviews please) 2016/11/14 22:12:34 Done.
313 invalidate();
314 }
315
316 public SurfaceHolder getHolder() {
317 return mForegroundSurfaceView.getHolder();
225 } 318 }
226 319
227 @Override 320 @Override
228 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 321 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
229 if (mNativeCompositorView == 0) return; 322 if (mNativeCompositorView == 0) return;
323
324 if (isBackgroundHolder(holder)) return;
boliu 2016/10/12 23:33:34 suggestion: might be useful have an inner static c
liberato (no reviews please) 2016/11/14 22:12:35 after refactoring, i'm not sure that this is still
325
230 nativeSurfaceChanged(mNativeCompositorView, format, width, height, holde r.getSurface()); 326 nativeSurfaceChanged(mNativeCompositorView, format, width, height, holde r.getSurface());
231 mRenderHost.onPhysicalBackingSizeChanged(width, height); 327 mRenderHost.onPhysicalBackingSizeChanged(width, height);
232 mSurfaceWidth = width; 328 mSurfaceWidth = width;
233 mSurfaceHeight = height; 329 mSurfaceHeight = height;
234 } 330 }
235 331
236 @Override 332 @Override
237 public void surfaceCreated(SurfaceHolder holder) { 333 public void surfaceCreated(SurfaceHolder holder) {
238 if (mNativeCompositorView == 0) return; 334 if (mNativeCompositorView == 0) return;
335
336 if (isBackgroundHolder(holder)) {
337 // We requested that background view as part of a surface swap.
338 // Switch the compositor.
339 nativeSurfaceDestroyed(mNativeCompositorView);
340 nativeSetOverlayVideoMode(
341 mNativeCompositorView, mVirtualPixelFormat == PixelFormat.TR ANSLUCENT);
342
343 // Switch the primary and secondary surfaces.
344 SurfaceView tmp = mForegroundSurfaceView;
345 mForegroundSurfaceView = mBackgroundSurfaceView;
346 mBackgroundSurfaceView = tmp;
347
348 // We will wait to actually hide the new background surface until
349 // the foreground surface has something to show. Note that,
350 // unfortunately, the new foreground surface is actually z-ordered
351 // below the new background, so mBackgroundSurfaceView will prevent
352 // new compositor updates from showing until we hide it.
353 mHideBackgroundPending = true;
354 mFramesUntilHide = 1;
355
356 // Refresh any properties that we proxy for the SurfaceView.
357 mForegroundSurfaceView.setWillNotDraw(mWillNotDraw);
358 mForegroundSurfaceView.setBackground(getBackground());
359 }
360
239 nativeSurfaceCreated(mNativeCompositorView); 361 nativeSurfaceCreated(mNativeCompositorView);
240 mRenderHost.onSurfaceCreated(); 362 mRenderHost.onSurfaceCreated();
241 } 363 }
242 364
243 @Override 365 @Override
244 public void surfaceDestroyed(SurfaceHolder holder) { 366 public void surfaceDestroyed(SurfaceHolder holder) {
245 if (mNativeCompositorView == 0) return; 367 if (mNativeCompositorView == 0) return;
368
369 // If the non-primary surface has been destroyed, then ignore it.
370 if (isBackgroundHolder(holder)) return;
371
246 nativeSurfaceDestroyed(mNativeCompositorView); 372 nativeSurfaceDestroyed(mNativeCompositorView);
247 } 373 }
248 374
249 @Override 375 @Override
250 public void onWindowVisibilityChanged(int visibility) { 376 public void onWindowVisibilityChanged(int visibility) {
251 super.onWindowVisibilityChanged(visibility); 377 super.onWindowVisibilityChanged(visibility);
252 if (mWindowAndroid == null) return; 378 if (mWindowAndroid == null) return;
253 if (visibility == View.GONE) { 379 if (visibility == View.GONE) {
254 mWindowAndroid.onVisibilityChanged(false); 380 mWindowAndroid.onVisibilityChanged(false);
255 } else if (visibility == View.VISIBLE) { 381 } else if (visibility == View.VISIBLE) {
(...skipping 15 matching lines...) Expand all
271 */ 397 */
272 @CalledByNative 398 @CalledByNative
273 private void onJellyBeanSurfaceDisconnectWorkaround(boolean inOverlayMode) { 399 private void onJellyBeanSurfaceDisconnectWorkaround(boolean inOverlayMode) {
274 // There is a bug in JellyBean because of which we will not be able to 400 // There is a bug in JellyBean because of which we will not be able to
275 // reconnect to the existing Surface after we launch a new GPU process. 401 // reconnect to the existing Surface after we launch a new GPU process.
276 // We simply trick the JB Android code to allocate a new Surface. 402 // We simply trick the JB Android code to allocate a new Surface.
277 // It does a strict comparison between the current format and the reques ted 403 // It does a strict comparison between the current format and the reques ted
278 // one, even if they are the same in practice. Furthermore, the format 404 // one, even if they are the same in practice. Furthermore, the format
279 // does not matter here since the producer-side EGL config overwrites it 405 // does not matter here since the producer-side EGL config overwrites it
280 // (but transparency might matter). 406 // (but transparency might matter).
281 switch (mCurrentPixelFormat) { 407 switch (mActualPixelFormat) {
282 case PixelFormat.OPAQUE: 408 case PixelFormat.OPAQUE:
283 mCurrentPixelFormat = PixelFormat.RGBA_8888; 409 mActualPixelFormat = PixelFormat.RGBA_8888;
284 break; 410 break;
285 case PixelFormat.RGBA_8888: 411 case PixelFormat.RGBA_8888:
286 mCurrentPixelFormat = inOverlayMode 412 mActualPixelFormat = inOverlayMode ? PixelFormat.TRANSLUCENT : P ixelFormat.OPAQUE;
287 ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
288 break; 413 break;
289 case PixelFormat.TRANSLUCENT: 414 case PixelFormat.TRANSLUCENT:
290 mCurrentPixelFormat = PixelFormat.RGBA_8888; 415 mActualPixelFormat = PixelFormat.RGBA_8888;
291 break; 416 break;
292 default: 417 default:
293 assert false; 418 assert false;
294 Log.e(TAG, "Unknown current pixel format."); 419 Log.e(TAG, "Unknown current pixel format.");
295 } 420 }
296 getHolder().setFormat(mCurrentPixelFormat); 421 getHolder().setFormat(mActualPixelFormat);
297 } 422 }
298 423
299 /** 424 /**
300 * Request compositor view to render a frame. 425 * Request compositor view to render a frame.
301 */ 426 */
302 public void requestRender() { 427 public void requestRender() {
303 if (mNativeCompositorView != 0) nativeSetNeedsComposite(mNativeComposito rView); 428 if (mNativeCompositorView != 0) nativeSetNeedsComposite(mNativeComposito rView);
304 } 429 }
305 430
431 private boolean isBackgroundHolder(SurfaceHolder holder) {
432 return mBackgroundSurfaceView != null && holder == mBackgroundSurfaceVie w.getHolder();
433 }
434
306 @CalledByNative 435 @CalledByNative
307 private void onSwapBuffersCompleted(int pendingSwapBuffersCount) { 436 private void onSwapBuffersCompleted(int pendingSwapBuffersCount) {
308 // Clear the color used to cover the uninitialized surface. 437 // Clear the color used to cover the uninitialized surface.
309 if (getBackground() != null) { 438 if (getBackground() != null) {
310 postDelayed(new Runnable() { 439 postDelayed(new Runnable() {
311 @Override 440 @Override
312 public void run() { 441 public void run() {
313 setBackgroundResource(0); 442 setBackgroundResource(0);
314 } 443 }
315 }, mFramePresentationDelay); 444 }, mFramePresentationDelay);
316 } 445 }
317 446
447 // If we're in the middle of a surface swap, then see if we've received
448 // enough frames to hide the outgoing surface.
449 if (mHideBackgroundPending) {
450 if (mFramesUntilHide > 0) {
boliu 2016/10/12 23:33:34 I'm not sure what the two frame delay is for. The
liberato (no reviews please) 2016/11/14 22:12:34 arbitrary delay, unfortunately.
451 mFramesUntilHide--;
452 // Make sure that there actually will be a frame.
453 requestRender();
454 } else {
455 // Remove the background so that we're sure that the underlying
456 // Surface is destroyed.
457 removeView(mBackgroundSurfaceView);
458 mHideBackgroundPending = false;
459 }
460 }
461
318 mRenderHost.onSwapBuffersCompleted(pendingSwapBuffersCount); 462 mRenderHost.onSwapBuffersCompleted(pendingSwapBuffersCount);
319 } 463 }
320 464
321 /** 465 /**
322 * Converts the layout into compositor layers. This is to be called on every frame the layout 466 * Converts the layout into compositor layers. This is to be called on every frame the layout
323 * is changing. 467 * is changing.
324 * @param provider Provides the layout to be rendered. 468 * @param provider Provides the layout to be rendered.
325 * @param forRotation Whether or not this is a special draw durin g a rotation. 469 * @param forRotation Whether or not this is a special draw durin g a rotation.
326 */ 470 */
327 public void finalizeLayers(final LayoutProvider provider, boolean forRotatio n, 471 public void finalizeLayers(final LayoutProvider provider, boolean forRotatio n,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 return mLastLayerCount; 522 return mLastLayerCount;
379 } 523 }
380 524
381 @Override 525 @Override
382 public int getOverlayTranslateY() { 526 public int getOverlayTranslateY() {
383 return mRenderHost.areTopControlsPermanentlyHidden() 527 return mRenderHost.areTopControlsPermanentlyHidden()
384 ? mRenderHost.getTopControlsHeightPixels() 528 ? mRenderHost.getTopControlsHeightPixels()
385 : mRenderHost.getVisibleViewport(mCacheVisibleViewport).top; 529 : mRenderHost.getVisibleViewport(mCacheVisibleViewport).top;
386 } 530 }
387 531
532 @Override
533 public void setWillNotDraw(boolean willNotDraw) {
534 mWillNotDraw = willNotDraw;
535 mForegroundSurfaceView.setWillNotDraw(mWillNotDraw);
536 }
537
538 @Override
539 public void setBackgroundDrawable(Drawable background) {
540 // We override setBackgroundDrawable since that's the common entry point
541 // from all the setBackground* calls in View. We still call to
542 // setBackground on the SurfaceView because SetBackgroundDrawable is
543 // depricated, and the semantics are the same I think.
544 super.setBackgroundDrawable(background);
545 mForegroundSurfaceView.setBackground(background);
546 }
547
548 /**
549 * Helper to create and attach a SurfaceView
550 */
551 private SurfaceView createSurfaceView() {
552 SurfaceView surfaceView = new SurfaceView(getContext());
553 surfaceView.setZOrderMediaOverlay(true);
554 surfaceView.setVisibility(View.INVISIBLE);
555 return surfaceView;
556 }
557
558 private void attachSurfaceView(SurfaceView surfaceView) {
559 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
560 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATC H_PARENT);
561 addView(surfaceView, lp);
562 }
563
388 // Implemented in native 564 // Implemented in native
389 private native long nativeInit(boolean lowMemDevice, long nativeWindowAndroi d, 565 private native long nativeInit(boolean lowMemDevice, long nativeWindowAndroi d,
390 LayerTitleCache layerTitleCache, TabContentManager tabContentManager ); 566 LayerTitleCache layerTitleCache, TabContentManager tabContentManager );
391 private native void nativeDestroy(long nativeCompositorView); 567 private native void nativeDestroy(long nativeCompositorView);
392 private native ResourceManager nativeGetResourceManager(long nativeComposito rView); 568 private native ResourceManager nativeGetResourceManager(long nativeComposito rView);
393 private native void nativeSurfaceCreated(long nativeCompositorView); 569 private native void nativeSurfaceCreated(long nativeCompositorView);
394 private native void nativeSurfaceDestroyed(long nativeCompositorView); 570 private native void nativeSurfaceDestroyed(long nativeCompositorView);
395 private native void nativeSurfaceChanged( 571 private native void nativeSurfaceChanged(
396 long nativeCompositorView, int format, int width, int height, Surfac e surface); 572 long nativeCompositorView, int format, int width, int height, Surfac e surface);
397 private native void nativeFinalizeLayers(long nativeCompositorView); 573 private native void nativeFinalizeLayers(long nativeCompositorView);
398 private native void nativeSetNeedsComposite(long nativeCompositorView); 574 private native void nativeSetNeedsComposite(long nativeCompositorView);
399 private native void nativeSetLayoutViewport(long nativeCompositorView, float x, float y, 575 private native void nativeSetLayoutViewport(long nativeCompositorView, float x, float y,
400 float width, float height, float visibleXOffset, float visibleYOffse t, 576 float width, float height, float visibleXOffset, float visibleYOffse t,
401 float dpToPixel); 577 float dpToPixel);
402 private native void nativeSetOverlayVideoMode(long nativeCompositorView, boo lean enabled); 578 private native void nativeSetOverlayVideoMode(long nativeCompositorView, boo lean enabled);
403 private native void nativeSetSceneLayer(long nativeCompositorView, SceneLaye r sceneLayer); 579 private native void nativeSetSceneLayer(long nativeCompositorView, SceneLaye r sceneLayer);
404 } 580 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698