Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |