| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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.content.Context; | 7 import android.content.Context; |
| 8 import android.graphics.PixelFormat; | 8 import android.graphics.PixelFormat; |
| 9 import android.graphics.drawable.Drawable; | 9 import android.graphics.drawable.Drawable; |
| 10 import android.view.SurfaceHolder; | 10 import android.view.SurfaceHolder; |
| 11 import android.view.SurfaceView; | 11 import android.view.SurfaceView; |
| 12 import android.view.View; | 12 import android.view.View; |
| 13 import android.view.ViewGroup; | 13 import android.view.ViewGroup; |
| 14 import android.widget.FrameLayout; | 14 import android.widget.FrameLayout; |
| 15 | 15 |
| 16 import org.chromium.base.annotations.UsedByReflection; |
| 17 |
| 16 /** | 18 /** |
| 17 * Manage multiple SurfaceViews for the compositor, so that transitions between | 19 * Manage multiple SurfaceViews for the compositor, so that transitions between |
| 18 * surfaces with and without an alpha channel can be visually smooth. | 20 * surfaces with and without an alpha channel can be visually smooth. |
| 19 * | 21 * |
| 20 * This class allows a client to request a 'translucent' or 'opaque' surface, an
d we will signal via | 22 * This class allows a client to request a 'translucent' or 'opaque' surface, an
d we will signal via |
| 21 * SurfaceHolder.Callback when it's ready. We guarantee that the client will re
ceive surfaceCreated | 23 * SurfaceHolder.Callback when it's ready. We guarantee that the client will re
ceive surfaceCreated |
| 22 * / surfaceDestroyed only for a surface that represents the most recently reque
sted PixelFormat. | 24 * / surfaceDestroyed only for a surface that represents the most recently reque
sted PixelFormat. |
| 23 * | 25 * |
| 24 * Internally, we maintain two SurfaceViews, since calling setFormat() to change
the PixelFormat | 26 * Internally, we maintain two SurfaceViews, since calling setFormat() to change
the PixelFormat |
| 25 * results in a visual glitch as the surface is torn down. crbug.com/679902 | 27 * results in a visual glitch as the surface is torn down. crbug.com/679902 |
| 26 * | 28 * |
| 27 * The client has the responsibility to call doneWithUnownedSurface() at some po
int between when we | 29 * The client has the responsibility to call doneWithUnownedSurface() at some po
int between when we |
| 28 * call back its surfaceCreated, when it is safe for us to hide the SurfaceView
with the wrong | 30 * call back its surfaceCreated, when it is safe for us to hide the SurfaceView
with the wrong |
| 29 * format. It is okay if it requests multiple surfaces without calling doneWith
UnownedSurface. | 31 * format. It is okay if it requests multiple surfaces without calling doneWith
UnownedSurface. |
| 30 * | 32 * |
| 31 * If the client requests the same format more than once in a row, it will still
receive destroyed / | 33 * If the client requests the same format more than once in a row, it will still
receive destroyed / |
| 32 * created / changed messages for it, even though we won't tear it down. | 34 * created / changed messages for it, even though we won't tear it down. |
| 33 * | 35 * |
| 34 * The full design doc is at https://goo.gl/aAmQzR . | 36 * The full design doc is at https://goo.gl/aAmQzR . |
| 35 */ | 37 */ |
| 36 class CompositorSurfaceManager implements SurfaceHolder.Callback { | 38 class CompositorSurfaceManager implements SurfaceHolder.Callback2 { |
| 39 public interface SurfaceHolderCallbackTarget { |
| 40 public void surfaceRedrawNeededAsync(SurfaceHolder holder, Runnable draw
ingFinished); |
| 41 public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height); |
| 42 public void surfaceCreated(SurfaceHolder holder); |
| 43 public void surfaceDestroyed(SurfaceHolder holder); |
| 44 } |
| 45 |
| 37 private static class SurfaceState { | 46 private static class SurfaceState { |
| 38 public SurfaceView surfaceView; | 47 public SurfaceView surfaceView; |
| 39 | 48 |
| 40 // Do we expect a surfaceCreated? | 49 // Do we expect a surfaceCreated? |
| 41 public boolean createPending; | 50 public boolean createPending; |
| 42 | 51 |
| 43 // Have we started destroying |surfaceView|, but haven't received surfac
eDestroyed yet? | 52 // Have we started destroying |surfaceView|, but haven't received surfac
eDestroyed yet? |
| 44 public boolean destroyPending; | 53 public boolean destroyPending; |
| 45 | 54 |
| 46 // Last PixelFormat that we received, or UNKNOWN if we don't know / don'
t want to cache it. | 55 // Last PixelFormat that we received, or UNKNOWN if we don't know / don'
t want to cache it. |
| 47 public int format; | 56 public int format; |
| 48 | 57 |
| 49 // Last known width, height for thsi surface. | 58 // Last known width, height for thsi surface. |
| 50 public int width; | 59 public int width; |
| 51 public int height; | 60 public int height; |
| 52 | 61 |
| 53 // Parent ViewGroup, or null. | 62 // Parent ViewGroup, or null. |
| 54 private ViewGroup mParent; | 63 private ViewGroup mParent; |
| 55 | 64 |
| 56 public SurfaceState(Context context, int format, SurfaceHolder.Callback
callback) { | 65 public SurfaceState(Context context, int format, SurfaceHolder.Callback2
callback) { |
| 57 surfaceView = new SurfaceView(context); | 66 surfaceView = new SurfaceView(context); |
| 58 surfaceView.setZOrderMediaOverlay(true); | 67 surfaceView.setZOrderMediaOverlay(true); |
| 59 surfaceView.setVisibility(View.VISIBLE); | 68 surfaceView.setVisibility(View.VISIBLE); |
| 60 surfaceHolder().setFormat(format); | 69 surfaceHolder().setFormat(format); |
| 61 surfaceHolder().addCallback(callback); | 70 surfaceHolder().addCallback(callback); |
| 62 | 71 |
| 63 // Set this to UNKNOWN until we get a format back. | 72 // Set this to UNKNOWN until we get a format back. |
| 64 this.format = PixelFormat.UNKNOWN; | 73 this.format = PixelFormat.UNKNOWN; |
| 65 } | 74 } |
| 66 | 75 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 // Surface that we last gave to the client with surfaceCreated. Cleared whe
n we call | 111 // Surface that we last gave to the client with surfaceCreated. Cleared whe
n we call |
| 103 // surfaceDestroyed on |mClient|. Note that it's not necessary that Android
has notified us | 112 // surfaceDestroyed on |mClient|. Note that it's not necessary that Android
has notified us |
| 104 // the surface has been destroyed; we deliberately keep it around until the
client tells us that | 113 // the surface has been destroyed; we deliberately keep it around until the
client tells us that |
| 105 // it's okay to get rid of it. | 114 // it's okay to get rid of it. |
| 106 private SurfaceState mOwnedByClient; | 115 private SurfaceState mOwnedByClient; |
| 107 | 116 |
| 108 // Surface that was most recently requested by the client. | 117 // Surface that was most recently requested by the client. |
| 109 private SurfaceState mRequestedByClient; | 118 private SurfaceState mRequestedByClient; |
| 110 | 119 |
| 111 // Client that we notify about surface change events. | 120 // Client that we notify about surface change events. |
| 112 private SurfaceHolder.Callback mClient; | 121 private SurfaceHolderCallbackTarget mClient; |
| 113 | 122 |
| 114 // View to which we'll attach the SurfaceView. | 123 // View to which we'll attach the SurfaceView. |
| 115 private final ViewGroup mParentView; | 124 private final ViewGroup mParentView; |
| 116 | 125 |
| 117 public CompositorSurfaceManager(ViewGroup parentView, SurfaceHolder.Callback
client) { | 126 public CompositorSurfaceManager(ViewGroup parentView, SurfaceHolderCallbackT
arget client) { |
| 118 mParentView = parentView; | 127 mParentView = parentView; |
| 119 mClient = client; | 128 mClient = client; |
| 120 | 129 |
| 121 mTranslucent = new SurfaceState(parentView.getContext(), PixelFormat.TRA
NSLUCENT, this); | 130 mTranslucent = new SurfaceState(parentView.getContext(), PixelFormat.TRA
NSLUCENT, this); |
| 122 mOpaque = new SurfaceState(mParentView.getContext(), PixelFormat.OPAQUE,
this); | 131 mOpaque = new SurfaceState(mParentView.getContext(), PixelFormat.OPAQUE,
this); |
| 123 } | 132 } |
| 124 | 133 |
| 125 /** | 134 /** |
| 126 * Turn off everything. | 135 * Turn off everything. |
| 127 */ | 136 */ |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 // client has requested a different surface but hasn't gotten it yet, th
en skip this. | 256 // client has requested a different surface but hasn't gotten it yet, th
en skip this. |
| 248 if (state == mOwnedByClient && state == mRequestedByClient) { | 257 if (state == mOwnedByClient && state == mRequestedByClient) { |
| 249 state.width = width; | 258 state.width = width; |
| 250 state.height = height; | 259 state.height = height; |
| 251 state.format = format; | 260 state.format = format; |
| 252 mClient.surfaceChanged(holder, format, width, height); | 261 mClient.surfaceChanged(holder, format, width, height); |
| 253 } | 262 } |
| 254 } | 263 } |
| 255 | 264 |
| 256 @Override | 265 @Override |
| 266 public void surfaceRedrawNeeded(SurfaceHolder holder) { |
| 267 // Intentionally not implemented. |
| 268 } |
| 269 |
| 270 // TODO(boliu): Mark this override instead. |
| 271 @UsedByReflection("Android") |
| 272 public void surfaceRedrawNeededAsync(SurfaceHolder holder, Runnable drawingF
inished) { |
| 273 mClient.surfaceRedrawNeededAsync(holder, drawingFinished); |
| 274 } |
| 275 |
| 276 @Override |
| 257 public void surfaceCreated(SurfaceHolder holder) { | 277 public void surfaceCreated(SurfaceHolder holder) { |
| 258 SurfaceState state = getStateForHolder(holder); | 278 SurfaceState state = getStateForHolder(holder); |
| 259 assert state != null; | 279 assert state != null; |
| 260 // Note that |createPending| might not be set, if Android destroyed and
recreated this | 280 // Note that |createPending| might not be set, if Android destroyed and
recreated this |
| 261 // surface on its own. | 281 // surface on its own. |
| 262 | 282 |
| 263 if (state != mRequestedByClient) { | 283 if (state != mRequestedByClient) { |
| 264 // Surface is created, but it's not the one that's been requested mo
st recently. Just | 284 // Surface is created, but it's not the one that's been requested mo
st recently. Just |
| 265 // destroy it again. | 285 // destroy it again. |
| 266 detachSurfaceLater(state); | 286 detachSurfaceLater(state); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 | 471 |
| 452 state.destroyPending = true; | 472 state.destroyPending = true; |
| 453 mParentView.post(new Runnable() { | 473 mParentView.post(new Runnable() { |
| 454 @Override | 474 @Override |
| 455 public void run() { | 475 public void run() { |
| 456 detachSurfaceNow(state); | 476 detachSurfaceNow(state); |
| 457 } | 477 } |
| 458 }); | 478 }); |
| 459 } | 479 } |
| 460 } | 480 } |
| OLD | NEW |