|
|
Chromium Code Reviews|
Created:
4 years, 7 months ago by ccameron Modified:
4 years, 7 months ago CC:
Aaron Boodman, abarth-chromium, ben+mojo_chromium.org, cc-bugs_chromium.org, chromium-reviews, darin (slow to review), darin-cc_chromium.org, erikchen, jam, piman+watch_chromium.org, qsr+mojo_chromium.org, viettrungluu+watch_chromium.org, yzshen+watch_chromium.org, piman Base URL:
https://chromium.googlesource.com/chromium/src.git@master Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
Descriptioncc: Add GpuMemoryBufferHandle to TextureMailbox
In cc::ResourceProvider, this popualtes the GpuMemoryBuffer handle but
does not consume it either in the renderer or in the browser. That
change will come in a non-plumbing patch.
BUG=604052
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Patch Set 1 : Trim #
Total comments: 1
Patch Set 2 : Fix exo #Patch Set 3 : Fix exo #
Total comments: 3
Messages
Total messages: 26 (9 generated)
Description was changed from ========== cc: Add GpuMemoryBufferHandle to TextureMailbox Populate the Mach port for IOSurface GpuMemoryBuffer handles. In cc::ResourceProvider, this popualtes the GpuMemoryBuffer handle but does not consume it either in the renderer or in the browser. That change will come in a non-plumbing patch. BUG=604052 ========== to ========== cc: Add GpuMemoryBufferHandle to TextureMailbox Populate the Mach port for IOSurface GpuMemoryBuffer handles. In cc::ResourceProvider, this popualtes the GpuMemoryBuffer handle but does not consume it either in the renderer or in the browser. That change will come in a non-plumbing patch. BUG=604052 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel ==========
Description was changed from ========== cc: Add GpuMemoryBufferHandle to TextureMailbox Populate the Mach port for IOSurface GpuMemoryBuffer handles. In cc::ResourceProvider, this popualtes the GpuMemoryBuffer handle but does not consume it either in the renderer or in the browser. That change will come in a non-plumbing patch. BUG=604052 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_optional_gpu_tests_rel;tryserver.chromium.mac:mac_optional_gpu_tests_rel;tryserver.chromium.win:win_optional_gpu_tests_rel ========== to ========== cc: Add GpuMemoryBufferHandle to TextureMailbox Populate the Mach port for IOSurface GpuMemoryBuffer handles. In cc::ResourceProvider, this popualtes the GpuMemoryBuffer handle but does not consume it either in the renderer or in the browser. That change will come in a non-plumbing patch. BUG=604052 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel ==========
Description was changed from ========== cc: Add GpuMemoryBufferHandle to TextureMailbox Populate the Mach port for IOSurface GpuMemoryBuffer handles. In cc::ResourceProvider, this popualtes the GpuMemoryBuffer handle but does not consume it either in the renderer or in the browser. That change will come in a non-plumbing patch. BUG=604052 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel ========== to ========== cc: Add GpuMemoryBufferHandle to TextureMailbox In cc::ResourceProvider, this popualtes the GpuMemoryBuffer handle but does not consume it either in the renderer or in the browser. That change will come in a non-plumbing patch. BUG=604052 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel ==========
ccameron@chromium.org changed reviewers: + reveman@chromium.org
Patchset #1 (id:1) has been deleted
Patchset #1 (id:20001) has been deleted
Patchset #1 (id:40001) has been deleted
ptal -- just plumbing for now. https://codereview.chromium.org/1930193002/diff/60001/cc/blink/web_external_t... File cc/blink/web_external_texture_layer_impl.cc (right): https://codereview.chromium.org/1930193002/diff/60001/cc/blink/web_external_t... cc/blink/web_external_texture_layer_impl.cc:98: gfx::GpuMemoryBufferHandle(), client_mailbox.allowOverlay, false); For GMBs created in Blink, we will need a way to put a handle (or something that can become a handle) in a client_mailbox.
https://codereview.chromium.org/1930193002/diff/100001/cc/resources/texture_m... File cc/resources/texture_mailbox.h (right): https://codereview.chromium.org/1930193002/diff/100001/cc/resources/texture_m... cc/resources/texture_mailbox.h:79: gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle_; Can this be a "gfx::GpuMemoryBuffer*" and the handle is only created when this needs to be sent over IPC? In the case of the UI compositor there might not be a need for creating a handle.
I think the GMBH works a bit better than GMB here (perhaps just on Mac), and it appears that the video code is built around GMBH. https://codereview.chromium.org/1930193002/diff/100001/cc/resources/texture_m... File cc/resources/texture_mailbox.h (right): https://codereview.chromium.org/1930193002/diff/100001/cc/resources/texture_m... cc/resources/texture_mailbox.h:79: gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle_; On 2016/04/29 10:05:05, reveman wrote: > Can this be a "gfx::GpuMemoryBuffer*" and the handle is only created when this > needs to be sent over IPC? In the case of the UI compositor there might not be a > need for creating a handle. To me it felt much more natural to use a gfx::GpuMemoryBufferHandle here as compared with a pointer. Couple of reasons: - The cc::ResourceProvider takes ownership (via unique_ptr) of the GpuMemoryBuffer, which would create lifetime issues for the object (both cc/ and the caller want to own the GMB object) - I prototyped plugging this in to the video code, and the GMB handle fit very cleanly with https://code.google.com/p/chromium/codesearch#chromium/src/media/base/video_f... So to me it seems that passing via handle is better (but I do have a Mac-centric worldview).
On 2016/04/29 17:33:33, ccameron wrote: > I think the GMBH works a bit better than GMB here (perhaps just on Mac), and it > appears that the video code is built around GMBH. > > https://codereview.chromium.org/1930193002/diff/100001/cc/resources/texture_m... > File cc/resources/texture_mailbox.h (right): > > https://codereview.chromium.org/1930193002/diff/100001/cc/resources/texture_m... > cc/resources/texture_mailbox.h:79: gfx::GpuMemoryBufferHandle > gpu_memory_buffer_handle_; > On 2016/04/29 10:05:05, reveman wrote: > > Can this be a "gfx::GpuMemoryBuffer*" and the handle is only created when this > > needs to be sent over IPC? In the case of the UI compositor there might not be > a > > need for creating a handle. > > To me it felt much more natural to use a gfx::GpuMemoryBufferHandle here as > compared with a pointer. > > Couple of reasons: > - The cc::ResourceProvider takes ownership (via unique_ptr) of the > GpuMemoryBuffer, which would create lifetime issues for the object (both cc/ and > the caller want to own the GMB object) > > - I prototyped plugging this in to the video code, and the GMB handle fit very > cleanly with > https://code.google.com/p/chromium/codesearch#chromium/src/media/base/video_f... > > So to me it seems that passing via handle is better (but I do have a Mac-centric > worldview). Does this seem like a reasonable way to go?
pinging this again.
Sorry for the delay. This GMB case is very similar to the existing SharedBitmap case where we create the TextureMailbox using a raw pointer to the ShareBitmap. I would prefer if we followed that pattern. The ownership requirements should be the same so if we can reliable use a raw pointer in the SharedBitmap case I think we should be able to do the same for GMBs. The GMB handle is really just meant for IPC and shouldn't have to exist in a single process world so I'd rather not rely on it for non-IPC logic.
danakj@chromium.org changed reviewers: + jbauman@chromium.org
On 2016/05/03 18:58:32, reveman wrote: > Sorry for the delay. > > This GMB case is very similar to the existing SharedBitmap case where we create > the TextureMailbox using a raw pointer to the ShareBitmap. I would prefer if we > followed that pattern. The ownership requirements should be the same so if we > can reliable use a raw pointer in the SharedBitmap case I think we should be > able to do the same for GMBs. IIRC I think John was planning to remove these raw pointers and use a SharedBitmapId for software to make it look more like GPU mode? > The GMB handle is really just meant for IPC and shouldn't have to exist in a > single process world so I'd rather not rely on it for non-IPC logic.
On 2016/05/03 19:54:18, danakj wrote: > On 2016/05/03 18:58:32, reveman wrote: > > Sorry for the delay. > > > > This GMB case is very similar to the existing SharedBitmap case where we > create > > the TextureMailbox using a raw pointer to the ShareBitmap. I would prefer if > we > > followed that pattern. The ownership requirements should be the same so if we > > can reliable use a raw pointer in the SharedBitmap case I think we should be > > able to do the same for GMBs. > > IIRC I think John was planning to remove these raw pointers and use a > SharedBitmapId for software to make it look more like GPU mode? I don't think it's a good idea to pass around raw GMB pointers here -- it seems like a recipe for crashes. I'd be okay with a scoped_refptr for a GMB (which doesn't exist, but we could create such a thing). The sorts of things that would use this (video decode, etc) seem like they are only "by coincidence" in the same process (and in some cases, e.g, hardware accelerated decode, not in the same process). Consequently, I think GMBHs make sense in this context.
piman@chromium.org changed reviewers: + piman@chromium.org
https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... File content/common/cc_messages.h (right): https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... content/common/cc_messages.h:285: IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_handle) drive-by: 3 concerns here: 1- this means the browser has to trust handles coming from the renderer, this seems dangerous? The renderer already asked the browser to create that handle, so the browser should already knows about it, is there a way to refer to it other than by handle? 2- when receiving the message on the browser side, it creates a new handle there, which needs to be closed by someone - including in early outs of RenderWidgetHostImpl::OnSwapCompositorFrame. 3- on the sender side, there is a potential for a race if the GMB is destroyed on the compositor thread (or other thread) before the IO thread had a chance to send the message (which is async, so you don't know when that happens) - Very Bad Things happen in that case (potential for random handle to be sent and/or closed instead). The typical pattern is to duplicate the handle and have the IPC system close that after sending (see FileDescriptor::auto_close or SharedMemoryHandle::OwnershipPassesToIPC())
On 2016/05/03 23:40:49, piman wrote: > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > File content/common/cc_messages.h (right): > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > content/common/cc_messages.h:285: > IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_handle) > drive-by: 3 concerns here: > 1- this means the browser has to trust handles coming from the renderer, this > seems dangerous? The renderer already asked the browser to create that handle, > so the browser should already knows about it, is there a way to refer to it > other than by handle? The GMB is created by the GPU process -- AFAIK the browser is uninvolved. We could change things so that GMBs are created by the browser and then sent to the GPU process. Is that desirable? Even then, we'll still need to open IOSurfaces for frames decoded by accelerated decode in the GPU process. > 2- when receiving the message on the browser side, it creates a new handle > there, which needs to be closed by someone - including in early outs of > RenderWidgetHostImpl::OnSwapCompositorFrame. The handle has a scoped Mach port, which is closed on destruction. > 3- on the sender side, there is a potential for a race if the GMB is destroyed > on the compositor thread (or other thread) before the IO thread had a chance to > send the message (which is async, so you don't know when that happens) - Very > Bad Things happen in that case (potential for random handle to be sent and/or > closed instead). The typical pattern is to duplicate the handle and have the IPC > system close that after sending (see FileDescriptor::auto_close or > SharedMemoryHandle::OwnershipPassesToIPC()) The IOSurface is kept alive by the Mach port. As long as the port is alive, what happens in the sender is irrelevant, AFAIK.
On 2016/05/03 23:40:49, piman wrote: > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > File content/common/cc_messages.h (right): > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > content/common/cc_messages.h:285: > IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_handle) > drive-by: 3 concerns here: > 1- this means the browser has to trust handles coming from the renderer, this > seems dangerous? The renderer already asked the browser to create that handle, > so the browser should already knows about it, is there a way to refer to it > other than by handle? > 2- when receiving the message on the browser side, it creates a new handle > there, which needs to be closed by someone - including in early outs of > RenderWidgetHostImpl::OnSwapCompositorFrame. > 3- on the sender side, there is a potential for a race if the GMB is destroyed > on the compositor thread (or other thread) before the IO thread had a chance to > send the message (which is async, so you don't know when that happens) - Very > Bad Things happen in that case (potential for random handle to be sent and/or > closed instead). The typical pattern is to duplicate the handle and have the IPC > system close that after sending (see FileDescriptor::auto_close or > SharedMemoryHandle::OwnershipPassesToIPC()) Also, we can only send at most 7 fds in a single IPC - see https://code.google.com/p/chromium/codesearch#chromium/src/ipc/ipc_message_at... .
On 2016/05/03 23:54:20, ccameron wrote: > On 2016/05/03 23:40:49, piman wrote: > > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > > File content/common/cc_messages.h (right): > > > > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > > content/common/cc_messages.h:285: > > IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_handle) > > drive-by: 3 concerns here: > > > 1- this means the browser has to trust handles coming from the renderer, this > > seems dangerous? The renderer already asked the browser to create that handle, > > so the browser should already knows about it, is there a way to refer to it > > other than by handle? > > The GMB is created by the GPU process -- AFAIK the browser is uninvolved. > > We could change things so that GMBs are created by the browser and then sent to > the GPU process. Is that desirable? > > Even then, we'll still need to open IOSurfaces for frames decoded by accelerated > decode in the GPU process. > > > 2- when receiving the message on the browser side, it creates a new handle > > there, which needs to be closed by someone - including in early outs of > > RenderWidgetHostImpl::OnSwapCompositorFrame. > > The handle has a scoped Mach port, which is closed on destruction. > > > 3- on the sender side, there is a potential for a race if the GMB is destroyed > > on the compositor thread (or other thread) before the IO thread had a chance > to > > send the message (which is async, so you don't know when that happens) - Very > > Bad Things happen in that case (potential for random handle to be sent and/or > > closed instead). The typical pattern is to duplicate the handle and have the > IPC > > system close that after sending (see FileDescriptor::auto_close or > > SharedMemoryHandle::OwnershipPassesToIPC()) > > The IOSurface is kept alive by the Mach port. As long as the port is alive, what > happens in the sender is irrelevant, AFAIK. Ok, looks like this works on Mac (MachPortAttachmentMac handles refcounting) but not on POSIX or Windows. There's a similar issue if the IPC message is deserialized twice (e.g. by RenderFrameDevToolsAgentHost::OnSwapCompositorFrame and RenderWidgetHostImpl::OnSwapCompositorFrame).
On Tue, May 3, 2016 at 4:54 PM, <ccameron@chromium.org> wrote: > On 2016/05/03 23:40:49, piman wrote: > > > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > > File content/common/cc_messages.h (right): > > > > > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > > content/common/cc_messages.h:285: > > IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_handle) > > drive-by: 3 concerns here: > > > 1- this means the browser has to trust handles coming from the renderer, > this > > seems dangerous? The renderer already asked the browser to create that > handle, > > so the browser should already knows about it, is there a way to refer to > it > > other than by handle? > > The GMB is created by the GPU process -- AFAIK the browser is uninvolved. > Doesn't the renderer ask the browser to create it (which then delegates to the GPU process if needed)? Or are you using a different path than GpuMemoryBufferManager::AllocateGpuMemoryBuffer ? We could change things so that GMBs are created by the browser and then > sent to > the GPU process. Is that desirable? > > Even then, we'll still need to open IOSurfaces for frames decoded by > accelerated > decode in the GPU process. > For things that are created and used only in the GPU process, maybe we don't ever need to pass the handle to the renderer? > > > > 2- when receiving the message on the browser side, it creates a new > handle > > there, which needs to be closed by someone - including in early outs of > > RenderWidgetHostImpl::OnSwapCompositorFrame. > > The handle has a scoped Mach port, which is closed on destruction. > That is not true on other platforms... > > > > 3- on the sender side, there is a potential for a race if the GMB is > destroyed > > on the compositor thread (or other thread) before the IO thread had a > chance > to > > send the message (which is async, so you don't know when that happens) - > Very > > Bad Things happen in that case (potential for random handle to be sent > and/or > > closed instead). The typical pattern is to duplicate the handle and have > the > IPC > > system close that after sending (see FileDescriptor::auto_close or > > SharedMemoryHandle::OwnershipPassesToIPC()) > > The IOSurface is kept alive by the Mach port. As long as the port is > alive, what > happens in the sender is irrelevant, AFAIK. > ditto. > > https://codereview.chromium.org/1930193002/ > -- You received this message because you are subscribed to the Google Groups "Chromium-reviews" group. To unsubscribe from this group and stop receiving emails from it, send an email to chromium-reviews+unsubscribe@chromium.org.
On 2016/05/04 00:18:29, piman wrote: > On Tue, May 3, 2016 at 4:54 PM, <mailto:ccameron@chromium.org> wrote: > > > On 2016/05/03 23:40:49, piman wrote: > > > > > > > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > > > File content/common/cc_messages.h (right): > > > > > > > > > > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > > > content/common/cc_messages.h:285: > > > IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_handle) > > > drive-by: 3 concerns here: > > > > > 1- this means the browser has to trust handles coming from the renderer, > > this > > > seems dangerous? The renderer already asked the browser to create that > > handle, > > > so the browser should already knows about it, is there a way to refer to > > it > > > other than by handle? > > > > The GMB is created by the GPU process -- AFAIK the browser is uninvolved. > > > > Doesn't the renderer ask the browser to create it (which then delegates to > the GPU process if needed)? Or are you using a different path than > GpuMemoryBufferManager::AllocateGpuMemoryBuffer ? You're right -- it does go through there. In principle, the browser could open the resulting IOSurface and save it off. The following situation is cause for security concern/review: We are introducing a call to IOSurfaceLookupFromMachPort in the browser process, with a Mach port created in some other process. > We could change things so that GMBs are created by the browser and then > > sent to > > the GPU process. Is that desirable? > > > > Even then, we'll still need to open IOSurfaces for frames decoded by > > accelerated > > decode in the GPU process. > > > > For things that are created and used only in the GPU process, maybe we > don't ever need to pass the handle to the renderer? > > > > > > > > 2- when receiving the message on the browser side, it creates a new > > handle > > > there, which needs to be closed by someone - including in early outs of > > > RenderWidgetHostImpl::OnSwapCompositorFrame. > > > > The handle has a scoped Mach port, which is closed on destruction. > > > > That is not true on other platforms... > > > > > > > > 3- on the sender side, there is a potential for a race if the GMB is > > destroyed > > > on the compositor thread (or other thread) before the IO thread had a > > chance > > to > > > send the message (which is async, so you don't know when that happens) - > > Very > > > Bad Things happen in that case (potential for random handle to be sent > > and/or > > > closed instead). The typical pattern is to duplicate the handle and have > > the > > IPC > > > system close that after sending (see FileDescriptor::auto_close or > > > SharedMemoryHandle::OwnershipPassesToIPC()) > > > > The IOSurface is kept alive by the Mach port. As long as the port is > > alive, what > > happens in the sender is irrelevant, AFAIK. > > > > ditto. Then this approach is a non-starter. I'll go back to the contemplation phase. I also don't have any sort of design doc about what we're trying to do here, so writing one up would be a good first step.
Btw, would it be possible to pass around the gfx::GpuMemoryBufferId instead? And then look it up from creation time in the browser process?
On Tue, May 3, 2016 at 5:22 PM, <ccameron@chromium.org> wrote: > On 2016/05/04 00:18:29, piman wrote: > > On Tue, May 3, 2016 at 4:54 PM, <mailto:ccameron@chromium.org> wrote: > > > > > On 2016/05/03 23:40:49, piman wrote: > > > > > > > > > > > > > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > > > > File content/common/cc_messages.h (right): > > > > > > > > > > > > > > > > > > https://codereview.chromium.org/1930193002/diff/100001/content/common/cc_mess... > > > > content/common/cc_messages.h:285: > > > > IPC_STRUCT_TRAITS_MEMBER(gpu_memory_buffer_handle) > > > > drive-by: 3 concerns here: > > > > > > > 1- this means the browser has to trust handles coming from the > renderer, > > > this > > > > seems dangerous? The renderer already asked the browser to create > that > > > handle, > > > > so the browser should already knows about it, is there a way to > refer to > > > it > > > > other than by handle? > > > > > > The GMB is created by the GPU process -- AFAIK the browser is > uninvolved. > > > > > > > Doesn't the renderer ask the browser to create it (which then delegates > to > > the GPU process if needed)? Or are you using a different path than > > GpuMemoryBufferManager::AllocateGpuMemoryBuffer ? > > You're right -- it does go through there. In principle, the browser could > open > the resulting IOSurface and save it off. > > The following situation is cause for security concern/review: > > We are introducing a call to IOSurfaceLookupFromMachPort in the browser > process, > with a Mach port created in some other process. > > > > We could change things so that GMBs are created by the browser and then > > > sent to > > > the GPU process. Is that desirable? > > > > > > Even then, we'll still need to open IOSurfaces for frames decoded by > > > accelerated > > > decode in the GPU process. > > > > > > > For things that are created and used only in the GPU process, maybe we > > don't ever need to pass the handle to the renderer? > > > > > > > > > > > > 2- when receiving the message on the browser side, it creates a new > > > handle > > > > there, which needs to be closed by someone - including in early outs > of > > > > RenderWidgetHostImpl::OnSwapCompositorFrame. > > > > > > The handle has a scoped Mach port, which is closed on destruction. > > > > > > > That is not true on other platforms... > > > > > > > > > > > > 3- on the sender side, there is a potential for a race if the GMB is > > > destroyed > > > > on the compositor thread (or other thread) before the IO thread had a > > > chance > > > to > > > > send the message (which is async, so you don't know when that > happens) - > > > Very > > > > Bad Things happen in that case (potential for random handle to be > sent > > > and/or > > > > closed instead). The typical pattern is to duplicate the handle and > have > > > the > > > IPC > > > > system close that after sending (see FileDescriptor::auto_close or > > > > SharedMemoryHandle::OwnershipPassesToIPC()) > > > > > > The IOSurface is kept alive by the Mach port. As long as the port is > > > alive, what > > > happens in the sender is irrelevant, AFAIK. > > > > > > > ditto. > > Then this approach is a non-starter. I'll go back to the contemplation > phase. > > I also don't have any sort of design doc about what we're trying to do > here, so > writing one up would be a good first step. > Awesome, thanks! > > https://codereview.chromium.org/1930193002/ > -- You received this message because you are subscribed to the Google Groups "Chromium-reviews" group. To unsubscribe from this group and stop receiving emails from it, send an email to chromium-reviews+unsubscribe@chromium.org.
On 2016/05/04 at 00:27:43, ccameron wrote: > Btw, would it be possible to pass around the gfx::GpuMemoryBufferId instead? And then look it up from creation time in the browser process? Yes, the gfx::GpuMemoryBufferId is in some sense the equivalent of SharedBitmapId so that sgtm. I'd like to handle SharedBitmaps and GMBs consistently as it will allow us to easily remove SharedBitmaps in favor of shmem backed GMBs in the future. ie. a SharedBitmap can be a small wrapper around GpuMemoryBufferImplSharedMemory. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
