Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
# include "mozilla/layers/TextureClient.h"
2013-08-12 03:17:23 +04:00
# include <stdint.h> // for uint8_t, uint32_t, etc
# include "Layers.h" // for Layer, etc
2013-12-20 20:46:29 +04:00
# include "gfx2DGlue.h"
2013-08-12 03:17:23 +04:00
# include "gfxPlatform.h" // for gfxPlatform
2015-10-16 15:46:33 +03:00
# include "mozilla/Atomics.h"
2013-08-12 03:17:23 +04:00
# include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
# include "mozilla/layers/CompositableForwarder.h"
# include "mozilla/layers/ISurfaceAllocator.h"
# include "mozilla/layers/ImageDataSerializer.h"
2013-05-23 11:17:10 +04:00
# include "mozilla/layers/YCbCrImageDataSerializer.h"
2013-08-12 03:17:23 +04:00
# include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
2014-02-27 01:36:35 +04:00
# include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
2014-07-15 11:59:34 +04:00
# include "ImageContainer.h" // for PlanarYCbCrData, etc
2013-10-16 05:00:30 +04:00
# include "mozilla/gfx/2D.h"
2014-12-09 21:19:29 +03:00
# include "mozilla/gfx/Logging.h" // for gfxDebug
2014-03-08 01:34:04 +04:00
# include "mozilla/layers/TextureClientOGL.h"
2014-04-28 15:29:13 +04:00
# include "mozilla/layers/PTextureChild.h"
2014-12-18 21:32:45 +03:00
# include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning
# include "nsPrintfCString.h" // for nsPrintfCString
# include "LayersLogging.h" // for AppendToString
# include "gfxUtils.h" // for gfxUtils::GetAsLZ4Base64Str
2015-11-06 18:56:03 +03:00
# include "IPDLActor.h"
2014-03-08 01:34:04 +04:00
# ifdef XP_WIN
# include "mozilla/layers/TextureD3D9.h"
# include "mozilla/layers/TextureD3D11.h"
2014-07-11 01:29:40 +04:00
# include "mozilla/layers/TextureDIB.h"
2014-03-08 01:34:04 +04:00
# include "gfxWindowsPlatform.h"
# include "gfx2DGlue.h"
# endif
# ifdef MOZ_X11
# include "mozilla/layers/TextureClientX11.h"
# ifdef GL_PROVIDER_GLX
# include "GLXLibrary.h"
# endif
# endif
# ifdef MOZ_WIDGET_GONK
# include <cutils/properties.h>
# include "mozilla/layers/GrallocTextureClient.h"
# endif
2013-08-12 06:21:17 +04:00
2014-08-22 23:26:56 +04:00
# ifdef MOZ_WIDGET_ANDROID
2013-08-19 17:59:27 +04:00
# include "gfxReusableImageSurfaceWrapper.h"
# else
# include "gfxReusableSharedImageSurfaceWrapper.h"
# include "gfxSharedImageSurface.h"
# endif
2014-03-10 22:34:57 +04:00
#if 0
# define RECYCLE_LOG(...) printf_stderr(__VA_ARGS__)
# else
# define RECYCLE_LOG(...) do { } while (0)
# endif
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
namespace mozilla {
namespace layers {
2014-05-22 14:11:45 +04:00
using namespace mozilla : : ipc ;
using namespace mozilla : : gl ;
using namespace mozilla : : gfx ;
2015-11-20 18:55:26 +03:00
struct ReleaseKeepAlive : public nsRunnable
2015-03-26 03:05:25 +03:00
{
2015-11-20 18:55:26 +03:00
NS_IMETHOD Run ( )
{
mKeep = nullptr ;
return NS_OK ;
}
2015-03-26 03:05:25 +03:00
2015-11-20 18:55:26 +03:00
UniquePtr < KeepAlive > mKeep ;
} ;
2015-11-20 16:25:03 +03:00
2013-12-12 05:44:45 +04:00
/**
* TextureChild is the content - side incarnation of the PTexture IPDL actor .
*
* TextureChild is used to synchronize a texture client and its corresponding
* TextureHost if needed ( a TextureClient that is not shared with the compositor
* does not have a TextureChild )
*
* During the deallocation phase , a TextureChild may hold its recently destroyed
* TextureClient ' s data until the compositor side confirmed that it is safe to
* deallocte or recycle the it .
*/
2015-11-06 18:56:03 +03:00
class TextureChild final : public ChildActor < PTextureChild >
2013-12-12 05:44:44 +04:00
{
2015-03-26 03:05:25 +03:00
~ TextureChild ( )
{
2015-11-20 18:55:26 +03:00
if ( mKeep & & mMainThreadOnly & & ! NS_IsMainThread ( ) ) {
RefPtr < ReleaseKeepAlive > release = new ReleaseKeepAlive ( ) ;
release - > mKeep = Move ( mKeep ) ;
NS_DispatchToMainThread ( release ) ;
}
2015-03-26 03:05:25 +03:00
}
2013-12-12 05:44:44 +04:00
public :
2014-04-14 23:04:25 +04:00
NS_INLINE_DECL_THREADSAFE_REFCOUNTING ( TextureChild )
2013-12-12 05:44:45 +04:00
TextureChild ( )
: mForwarder ( nullptr )
2015-10-16 15:46:33 +03:00
, mMonitor ( " TextureChild " )
, mTextureClient ( nullptr )
, mDestroyed ( false )
2015-10-16 16:22:06 +03:00
, mMainThreadOnly ( false )
, mIPCOpen ( false )
2015-11-20 18:55:26 +03:00
{
}
2013-12-12 05:44:45 +04:00
2015-11-20 18:55:26 +03:00
bool Recv__delete__ ( ) override ;
2013-12-12 05:44:45 +04:00
2015-03-21 19:28:04 +03:00
bool RecvCompositorRecycle ( ) override
2014-03-10 22:34:57 +04:00
{
2015-06-05 03:15:38 +03:00
RECYCLE_LOG ( " [CLIENT] Receive recycle %p (%p) \n " , mTextureClient , mWaitForRecycle . get ( ) ) ;
2014-03-10 22:34:57 +04:00
mWaitForRecycle = nullptr ;
return true ;
}
void WaitForCompositorRecycle ( )
{
2015-10-16 15:46:33 +03:00
{
MonitorAutoLock mon ( mMonitor ) ;
mWaitForRecycle = mDestroyed ? nullptr : mTextureClient ;
}
2015-06-05 03:15:38 +03:00
RECYCLE_LOG ( " [CLIENT] Wait for recycle %p \n " , mWaitForRecycle . get ( ) ) ;
2015-11-06 18:56:03 +03:00
MOZ_ASSERT ( CanSend ( ) ) ;
2014-03-10 22:34:57 +04:00
SendClientRecycle ( ) ;
}
2013-12-12 05:44:45 +04:00
CompositableForwarder * GetForwarder ( ) { return mForwarder ; }
ISurfaceAllocator * GetAllocator ( ) { return mForwarder ; }
2015-03-21 19:28:04 +03:00
void ActorDestroy ( ActorDestroyReason why ) override ;
2013-12-12 05:44:55 +04:00
2013-12-21 01:44:30 +04:00
bool IPCOpen ( ) const { return mIPCOpen ; }
2013-12-12 05:44:55 +04:00
private :
2013-12-21 01:44:30 +04:00
// AddIPDLReference and ReleaseIPDLReference are only to be called by CreateIPDLActor
// and DestroyIPDLActor, respectively. We intentionally make them private to prevent misuse.
// The purpose of these methods is to be aware of when the IPC system around this
// actor goes down: mIPCOpen is then set to false.
void AddIPDLReference ( ) {
MOZ_ASSERT ( mIPCOpen = = false ) ;
mIPCOpen = true ;
AddRef ( ) ;
}
void ReleaseIPDLReference ( ) {
MOZ_ASSERT ( mIPCOpen = = true ) ;
mIPCOpen = false ;
Release ( ) ;
}
2015-10-16 15:46:33 +03:00
void SetTextureClient ( TextureClient * aTextureClient ) {
MonitorAutoLock mon ( mMonitor ) ;
mTextureClient = aTextureClient ;
}
2015-10-18 08:24:48 +03:00
RefPtr < CompositableForwarder > mForwarder ;
RefPtr < TextureClient > mWaitForRecycle ;
2015-10-16 15:46:33 +03:00
// Monitor protecting mTextureClient.
Monitor mMonitor ;
2013-12-12 05:44:55 +04:00
TextureClient * mTextureClient ;
2015-11-20 18:55:26 +03:00
UniquePtr < KeepAlive > mKeep ;
2015-10-16 15:46:33 +03:00
Atomic < bool > mDestroyed ;
2015-03-26 03:05:25 +03:00
bool mMainThreadOnly ;
2013-12-21 01:44:30 +04:00
bool mIPCOpen ;
2013-12-12 05:44:44 +04:00
2013-12-12 05:44:55 +04:00
friend class TextureClient ;
2013-12-12 05:44:44 +04:00
} ;
2015-10-13 19:48:48 +03:00
bool
2015-11-20 18:55:26 +03:00
TextureChild : : Recv__delete__ ( )
2015-10-13 19:48:48 +03:00
{
2015-11-20 18:55:26 +03:00
return true ;
2015-10-13 19:48:48 +03:00
}
2015-10-15 18:53:37 +03:00
void
2015-11-20 18:55:26 +03:00
TextureChild : : ActorDestroy ( ActorDestroyReason why )
2015-10-15 18:53:37 +03:00
{
2015-11-20 18:55:26 +03:00
if ( mTextureClient ) {
mTextureClient - > mActor = nullptr ;
mTextureClient - > mAllocator = nullptr ;
2015-10-15 18:53:37 +03:00
}
2015-11-20 18:55:26 +03:00
mWaitForRecycle = nullptr ;
mKeep = nullptr ;
2015-10-15 18:53:37 +03:00
}
2013-12-12 05:44:44 +04:00
// static
PTextureChild *
TextureClient : : CreateIPDLActor ( )
{
2013-12-21 01:44:30 +04:00
TextureChild * c = new TextureChild ( ) ;
c - > AddIPDLReference ( ) ;
return c ;
2013-12-12 05:44:44 +04:00
}
// static
bool
TextureClient : : DestroyIPDLActor ( PTextureChild * actor )
{
2013-12-21 01:44:30 +04:00
static_cast < TextureChild * > ( actor ) - > ReleaseIPDLReference ( ) ;
2013-12-12 05:44:44 +04:00
return true ;
}
2014-02-25 08:23:41 +04:00
// static
TextureClient *
TextureClient : : AsTextureClient ( PTextureChild * actor )
{
2015-11-20 18:55:26 +03:00
return actor ? static_cast < TextureChild * > ( actor ) - > mTextureClient : nullptr ;
2014-03-10 22:34:57 +04:00
}
2015-09-30 19:17:30 +03:00
bool
TextureClient : : IsSharedWithCompositor ( ) const {
2015-11-20 18:55:26 +03:00
return mShared & & mActor & & mActor - > IPCOpen ( ) ;
2015-09-30 19:17:30 +03:00
}
2014-11-13 18:53:49 +03:00
void
TextureClient : : AddFlags ( TextureFlags aFlags )
{
MOZ_ASSERT ( ! IsSharedWithCompositor ( ) | |
( ( GetFlags ( ) & TextureFlags : : RECYCLE ) & & ! IsAddedToCompositableClient ( ) ) ) ;
mFlags | = aFlags ;
2015-11-20 18:55:26 +03:00
if ( mValid & & mActor & & ! mActor - > mDestroyed & & mActor - > IPCOpen ( ) ) {
2014-11-13 18:53:49 +03:00
mActor - > SendRecycleTexture ( mFlags ) ;
}
}
void
TextureClient : : RemoveFlags ( TextureFlags aFlags )
{
MOZ_ASSERT ( ! IsSharedWithCompositor ( ) | |
( ( GetFlags ( ) & TextureFlags : : RECYCLE ) & & ! IsAddedToCompositableClient ( ) ) ) ;
mFlags & = ~ aFlags ;
2015-11-20 18:55:26 +03:00
if ( mValid & & mActor & & ! mActor - > mDestroyed & & mActor - > IPCOpen ( ) ) {
2014-11-13 18:53:49 +03:00
mActor - > SendRecycleTexture ( mFlags ) ;
}
}
void
TextureClient : : RecycleTexture ( TextureFlags aFlags )
{
MOZ_ASSERT ( GetFlags ( ) & TextureFlags : : RECYCLE ) ;
mAddedToCompositableClient = false ;
if ( mFlags ! = aFlags ) {
mFlags = aFlags ;
2015-11-20 18:55:26 +03:00
if ( mValid & & mActor & & ! mActor - > mDestroyed & & mActor - > IPCOpen ( ) ) {
2014-11-13 18:53:49 +03:00
mActor - > SendRecycleTexture ( mFlags ) ;
}
}
}
2014-03-10 22:34:57 +04:00
void
TextureClient : : WaitForCompositorRecycle ( )
{
mActor - > WaitForCompositorRecycle ( ) ;
2014-02-25 08:23:41 +04:00
}
2014-11-13 18:53:49 +03:00
void
TextureClient : : SetAddedToCompositableClient ( )
{
if ( ! mAddedToCompositableClient ) {
mAddedToCompositableClient = true ;
}
}
2015-08-13 22:18:53 +03:00
/* static */ void
TextureClient : : TextureClientRecycleCallback ( TextureClient * aClient , void * aClosure )
{
MOZ_ASSERT ( aClient - > GetRecycleAllocator ( ) ) ;
aClient - > GetRecycleAllocator ( ) - > RecycleTextureClient ( aClient ) ;
}
void
TextureClient : : SetRecycleAllocator ( TextureClientRecycleAllocator * aAllocator )
{
mRecycleAllocator = aAllocator ;
if ( aAllocator ) {
SetRecycleCallback ( TextureClientRecycleCallback , nullptr ) ;
} else {
ClearRecycleCallback ( ) ;
}
}
2013-12-12 05:44:44 +04:00
bool
TextureClient : : InitIPDLActor ( CompositableForwarder * aForwarder )
{
2014-12-22 11:49:00 +03:00
MOZ_ASSERT ( aForwarder & & aForwarder - > GetMessageLoop ( ) = = mAllocator - > GetMessageLoop ( ) ) ;
2015-10-16 15:46:33 +03:00
if ( mActor & & ! mActor - > mDestroyed & & mActor - > GetForwarder ( ) = = aForwarder ) {
2014-02-10 06:24:27 +04:00
return true ;
}
2015-10-16 15:46:33 +03:00
MOZ_ASSERT ( ! mActor | | mActor - > mDestroyed , " Cannot use a texture on several IPC channels. " ) ;
2013-12-12 05:44:53 +04:00
2013-12-12 05:44:44 +04:00
SurfaceDescriptor desc ;
if ( ! ToSurfaceDescriptor ( desc ) ) {
return false ;
}
2015-10-06 09:39:00 +03:00
mActor = static_cast < TextureChild * > ( aForwarder - > CreateTexture ( desc , aForwarder - > GetCompositorBackendType ( ) , GetFlags ( ) ) ) ;
2014-01-22 02:06:18 +04:00
MOZ_ASSERT ( mActor ) ;
2013-12-12 05:44:45 +04:00
mActor - > mForwarder = aForwarder ;
2013-12-12 05:44:55 +04:00
mActor - > mTextureClient = this ;
2015-11-20 18:55:26 +03:00
mShared = true ;
2014-01-22 02:06:18 +04:00
return mActor - > IPCOpen ( ) ;
2013-12-12 05:44:44 +04:00
}
PTextureChild *
TextureClient : : GetIPDLActor ( )
{
return mActor ;
}
2015-11-20 18:55:26 +03:00
# ifdef MOZ_WIDGET_GONK
static bool
DisableGralloc ( SurfaceFormat aFormat , const gfx : : IntSize & aSizeHint )
{
if ( gfxPrefs : : DisableGralloc ( ) ) {
return true ;
}
if ( aFormat = = gfx : : SurfaceFormat : : A8 ) {
return true ;
}
# if ANDROID_VERSION <= 15
// Adreno 200 has a problem of drawing gralloc buffer width less than 64 and
// drawing gralloc buffer with a height 9px-16px.
// See Bug 983971.
if ( aSizeHint . width < 64 | | aSizeHint . height < 32 ) {
return true ;
}
# endif
return false ;
}
# endif
static
already_AddRefed < BufferTextureClient >
CreateBufferTextureClient ( ISurfaceAllocator * aAllocator ,
SurfaceFormat aFormat ,
TextureFlags aTextureFlags ,
gfx : : BackendType aMoz2DBackend )
{
if ( aAllocator - > IsSameProcess ( ) ) {
RefPtr < BufferTextureClient > result = new MemoryTextureClient ( aAllocator , aFormat ,
aMoz2DBackend ,
aTextureFlags ) ;
return result . forget ( ) ;
}
RefPtr < BufferTextureClient > result = new ShmemTextureClient ( aAllocator , aFormat ,
aMoz2DBackend ,
aTextureFlags ) ;
return result . forget ( ) ;
}
2015-08-07 03:27:36 +03:00
static inline gfx : : BackendType
2015-10-02 09:06:43 +03:00
BackendTypeForBackendSelector ( LayersBackend aLayersBackend , BackendSelector aSelector )
2015-08-07 03:27:36 +03:00
{
switch ( aSelector ) {
case BackendSelector : : Canvas :
return gfxPlatform : : GetPlatform ( ) - > GetPreferredCanvasBackend ( ) ;
case BackendSelector : : Content :
2015-10-02 09:06:43 +03:00
return gfxPlatform : : GetPlatform ( ) - > GetContentBackendFor ( aLayersBackend ) ;
2015-08-07 03:27:36 +03:00
default :
MOZ_ASSERT_UNREACHABLE ( " Unknown backend selector " ) ;
return gfx : : BackendType : : NONE ;
}
} ;
2014-07-29 15:16:57 +04:00
// static
2015-06-17 17:00:52 +03:00
already_AddRefed < TextureClient >
2015-10-06 09:40:13 +03:00
TextureClient : : CreateForDrawing ( CompositableForwarder * aAllocator ,
2014-07-29 15:16:57 +04:00
gfx : : SurfaceFormat aFormat ,
gfx : : IntSize aSize ,
2015-08-07 03:27:36 +03:00
BackendSelector aSelector ,
2014-07-29 15:16:57 +04:00
TextureFlags aTextureFlags ,
TextureAllocationFlags aAllocFlags )
2014-03-08 01:34:04 +04:00
{
2015-10-30 15:25:29 +03:00
MOZ_ASSERT ( aAllocator - > IPCOpen ( ) ) ;
if ( ! aAllocator | | ! aAllocator - > IPCOpen ( ) ) {
return nullptr ;
}
2015-11-18 18:59:11 +03:00
if ( ! gfx : : Factory : : AllowedSurfaceSize ( aSize ) ) {
return nullptr ;
}
2015-10-02 09:06:43 +03:00
LayersBackend parentBackend = aAllocator - > GetCompositorBackendType ( ) ;
gfx : : BackendType moz2DBackend = BackendTypeForBackendSelector ( parentBackend , aSelector ) ;
2014-03-18 01:35:20 +04:00
2015-11-20 18:55:26 +03:00
RefPtr < TextureClient > texture ;
2014-03-08 01:34:04 +04:00
2015-11-20 18:55:26 +03:00
# if defined(MOZ_WIDGET_GONK) || defined(XP_WIN)
2014-04-08 16:50:49 +04:00
int32_t maxTextureSize = aAllocator - > GetMaxTextureSize ( ) ;
# endif
2014-03-08 01:34:04 +04:00
# ifdef XP_WIN
2014-03-18 01:35:20 +04:00
if ( parentBackend = = LayersBackend : : LAYERS_D3D11 & &
2015-08-07 03:27:36 +03:00
( moz2DBackend = = gfx : : BackendType : : DIRECT2D | |
moz2DBackend = = gfx : : BackendType : : DIRECT2D1_1 ) & &
2014-07-29 15:16:57 +04:00
aSize . width < = maxTextureSize & &
Refactor graphics device initialization on Windows. (bug 1183910 part 1, r=mattwoodrow,bas)
This patch addresses a number of inconsistencies in the device initialization process, as well as simplifying it for future use. All device decisions are now explicitly made up-front during startup, rather than implicitly or on-demand. In addition a number of restrictions have been placed on when we can construct devices.
Full change list:
(1) We no longer attempt to use D3D11 if acceleration is disabled or D3D9 is preferred. This is a departure from our previous behavior, where we would construct these devices but then not use them as a compositor backend.
(2) D3D11 startup no longer creates a content device (this is reserved for D2D initialization).
(3) D2D is only attempted if we managed to create a D3D11 compositor device. This is a departure from previous behavior where if D3D11 was not used for compositing, we could still create its machinery to use D2D as a content backend.
(4) D2D 1.1 initialization is now directly responsible for creating a D3D11 content device.
(5) D2D 1.0 and 1.1 logic have been disentangled for clarity.
(6) UpdateRenderMode() has been split up, so we can update backend prefs out of band with device resets.
(7) mUseGDIFonts and mUseDirectWrite have been removed as their state was confusing. Instead, D2D now depends on DWrite initialization succeeding. If later we fail to get a DWrite font list, we revert our decision to use Direct2D.
(8) Device resets now clear a little more state, including the devices set in Moz2D Factory.
(9) We no longer create a DWrite text analyzer as it was unused.
2015-07-29 02:52:54 +03:00
aSize . height < = maxTextureSize )
{
2015-11-20 18:55:26 +03:00
texture = new TextureClientD3D11 ( aAllocator , aFormat , aTextureFlags ) ;
2014-03-08 01:34:04 +04:00
}
if ( parentBackend = = LayersBackend : : LAYERS_D3D9 & &
2015-08-07 03:27:36 +03:00
moz2DBackend = = gfx : : BackendType : : CAIRO & &
2014-03-08 01:34:04 +04:00
aAllocator - > IsSameProcess ( ) & &
2014-07-29 15:16:57 +04:00
aSize . width < = maxTextureSize & &
2015-07-27 18:47:29 +03:00
aSize . height < = maxTextureSize & &
2015-11-20 18:55:26 +03:00
NS_IsMainThread ( ) ) {
if ( gfxWindowsPlatform : : GetPlatform ( ) - > GetD3D9Device ( ) ) {
texture = new TextureClientD3D9 ( aAllocator , aFormat , aTextureFlags ) ;
}
2014-03-08 01:34:04 +04:00
}
2014-07-11 01:29:40 +04:00
2015-11-20 18:55:26 +03:00
if ( ! texture & & aFormat = = SurfaceFormat : : B8G8R8X8 & &
2015-06-22 06:16:13 +03:00
aAllocator - > IsSameProcess ( ) & &
2015-08-07 03:27:36 +03:00
moz2DBackend = = gfx : : BackendType : : CAIRO & &
2015-07-27 18:47:29 +03:00
NS_IsMainThread ( ) ) {
2015-11-20 18:55:26 +03:00
if ( aAllocator - > IsSameProcess ( ) ) {
texture = new TextureClientMemoryDIB ( aAllocator , aFormat , aTextureFlags ) ;
} else {
texture = new TextureClientShmemDIB ( aAllocator , aFormat , aTextureFlags ) ;
}
2014-07-11 01:29:40 +04:00
}
2014-03-08 01:34:04 +04:00
# endif
# ifdef MOZ_X11
gfxSurfaceType type =
gfxPlatform : : GetPlatform ( ) - > ScreenReferenceSurface ( ) - > GetType ( ) ;
2015-11-20 18:55:26 +03:00
if ( parentBackend = = LayersBackend : : LAYERS_BASIC & &
2015-08-07 03:27:36 +03:00
moz2DBackend = = gfx : : BackendType : : CAIRO & &
2014-07-29 15:16:57 +04:00
type = = gfxSurfaceType : : Xlib )
2014-03-08 01:34:04 +04:00
{
2015-11-20 18:55:26 +03:00
texture = new TextureClientX11 ( aAllocator , aFormat , aTextureFlags ) ;
2014-03-08 01:34:04 +04:00
}
# ifdef GL_PROVIDER_GLX
2015-11-20 18:55:26 +03:00
if ( parentBackend = = LayersBackend : : LAYERS_OPENGL & &
2014-03-08 01:34:04 +04:00
type = = gfxSurfaceType : : Xlib & &
aFormat ! = SurfaceFormat : : A8 & &
gl : : sGLXLibrary . UseTextureFromPixmap ( ) )
{
2015-11-20 18:55:26 +03:00
texture = new TextureClientX11 ( aAllocator , aFormat , aTextureFlags ) ;
2014-03-08 01:34:04 +04:00
}
# endif
# endif
# ifdef MOZ_WIDGET_GONK
2015-11-20 18:55:26 +03:00
if ( ! DisableGralloc ( aFormat , aSize ) ) {
// Don't allow Gralloc texture clients to exceed the maximum texture size.
// BufferTextureClients have code to handle tiling the surface client-side.
if ( aSize . width < = maxTextureSize & & aSize . height < = maxTextureSize ) {
texture = new GrallocTextureClientOGL ( aAllocator , aFormat , moz2DBackend ,
aTextureFlags ) ;
}
2014-03-08 01:34:04 +04:00
}
# endif
2015-11-20 18:55:26 +03:00
MOZ_ASSERT ( ! texture | | texture - > CanExposeDrawTarget ( ) , " texture cannot expose a DrawTarget? " ) ;
if ( texture & & texture - > AllocateForSurface ( aSize , aAllocFlags ) ) {
return texture . forget ( ) ;
}
if ( aAllocFlags & ALLOC_DISALLOW_BUFFERTEXTURECLIENT ) {
return nullptr ;
}
if ( texture ) {
NS_WARNING ( " Failed to allocate a TextureClient, falling back to BufferTextureClient. " ) ;
2015-11-20 16:25:03 +03:00
}
2014-07-29 15:16:57 +04:00
// Can't do any better than a buffer texture client.
2015-11-20 18:55:26 +03:00
texture = CreateBufferTextureClient ( aAllocator , aFormat , aTextureFlags , moz2DBackend ) ;
if ( ! texture - > AllocateForSurface ( aSize , aAllocFlags ) ) {
return nullptr ;
}
return texture . forget ( ) ;
2014-07-10 15:45:40 +04:00
}
// static
2015-11-20 18:55:26 +03:00
already_AddRefed < BufferTextureClient >
2014-07-10 15:45:40 +04:00
TextureClient : : CreateForRawBufferAccess ( ISurfaceAllocator * aAllocator ,
gfx : : SurfaceFormat aFormat ,
gfx : : IntSize aSize ,
gfx : : BackendType aMoz2DBackend ,
TextureFlags aTextureFlags ,
TextureAllocationFlags aAllocFlags )
{
2015-10-30 15:25:29 +03:00
MOZ_ASSERT ( aAllocator - > IPCOpen ( ) ) ;
if ( ! aAllocator | | ! aAllocator - > IPCOpen ( ) ) {
return nullptr ;
}
2015-11-18 18:59:11 +03:00
if ( ! gfx : : Factory : : AllowedSurfaceSize ( aSize ) ) {
return nullptr ;
}
2015-11-20 18:55:26 +03:00
RefPtr < BufferTextureClient > texture =
CreateBufferTextureClient ( aAllocator , aFormat ,
aTextureFlags , aMoz2DBackend ) ;
if ( texture ) {
if ( ! texture - > AllocateForSurface ( aSize , aAllocFlags ) ) {
return nullptr ;
}
2014-07-10 15:45:40 +04:00
}
2015-11-20 18:55:26 +03:00
return texture . forget ( ) ;
2014-07-10 15:45:40 +04:00
}
2014-07-10 15:48:29 +04:00
// static
2015-11-20 18:55:26 +03:00
already_AddRefed < BufferTextureClient >
2014-07-10 15:48:29 +04:00
TextureClient : : CreateForYCbCr ( ISurfaceAllocator * aAllocator ,
gfx : : IntSize aYSize ,
gfx : : IntSize aCbCrSize ,
StereoMode aStereoMode ,
TextureFlags aTextureFlags )
{
2015-11-20 18:55:26 +03:00
MOZ_ASSERT ( aAllocator - > IPCOpen ( ) ) ;
if ( ! aAllocator | | ! aAllocator - > IPCOpen ( ) ) {
2015-10-30 15:25:29 +03:00
return nullptr ;
}
2015-11-18 18:59:11 +03:00
if ( ! gfx : : Factory : : AllowedSurfaceSize ( aYSize ) ) {
return nullptr ;
}
2015-11-20 18:55:26 +03:00
RefPtr < BufferTextureClient > texture ;
if ( aAllocator - > IsSameProcess ( ) ) {
texture = new MemoryTextureClient ( aAllocator , gfx : : SurfaceFormat : : YUV ,
gfx : : BackendType : : NONE ,
aTextureFlags ) ;
} else {
texture = new ShmemTextureClient ( aAllocator , gfx : : SurfaceFormat : : YUV ,
gfx : : BackendType : : NONE ,
aTextureFlags ) ;
}
if ( ! texture - > AllocateForYCbCr ( aYSize , aCbCrSize , aStereoMode ) ) {
2014-07-10 15:48:29 +04:00
return nullptr ;
}
2015-11-20 18:55:26 +03:00
return texture . forget ( ) ;
2014-07-10 15:48:29 +04:00
}
2014-03-08 01:34:04 +04:00
// static
2015-11-20 18:55:26 +03:00
already_AddRefed < BufferTextureClient >
2014-07-22 16:17:31 +04:00
TextureClient : : CreateWithBufferSize ( ISurfaceAllocator * aAllocator ,
2015-11-20 18:55:26 +03:00
gfx : : SurfaceFormat aFormat ,
size_t aSize ,
TextureFlags aTextureFlags )
2014-03-08 01:34:04 +04:00
{
2015-10-30 15:25:29 +03:00
MOZ_ASSERT ( aAllocator - > IPCOpen ( ) ) ;
if ( ! aAllocator | | ! aAllocator - > IPCOpen ( ) ) {
return nullptr ;
}
2015-11-20 18:55:26 +03:00
RefPtr < BufferTextureClient > texture ;
if ( aAllocator - > IsSameProcess ( ) ) {
texture = new MemoryTextureClient ( aAllocator , gfx : : SurfaceFormat : : YUV ,
gfx : : BackendType : : NONE ,
aTextureFlags ) ;
} else {
texture = new ShmemTextureClient ( aAllocator , gfx : : SurfaceFormat : : YUV ,
gfx : : BackendType : : NONE ,
aTextureFlags ) ;
}
if ( ! texture - > Allocate ( aSize ) ) {
2014-07-22 16:17:31 +04:00
return nullptr ;
}
2015-11-20 18:55:26 +03:00
return texture . forget ( ) ;
2014-03-08 01:34:04 +04:00
}
2015-11-20 18:55:26 +03:00
TextureClient : : TextureClient ( ISurfaceAllocator * aAllocator , TextureFlags aFlags )
: mAllocator ( aAllocator )
, mFlags ( aFlags )
, mShared ( false )
, mValid ( true )
, mAddedToCompositableClient ( false )
2014-11-25 22:54:29 +03:00
# ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
2015-11-20 18:55:26 +03:00
, mPoolTracker ( nullptr )
2014-11-25 22:54:29 +03:00
# endif
2015-11-20 18:55:26 +03:00
{ }
TextureClient : : ~ TextureClient ( )
2014-07-22 19:49:05 +04:00
{
2015-11-20 18:55:26 +03:00
// All the destruction code that may lead to virtual method calls must
// be in Finalize() which is called just before the destructor.
}
void
TextureClient : : KeepUntilFullDeallocation ( UniquePtr < KeepAlive > aKeep , bool aMainThreadOnly )
{
MOZ_ASSERT ( mActor ) ;
MOZ_ASSERT ( ! mActor - > mKeep ) ;
mActor - > mKeep = Move ( aKeep ) ;
mActor - > mMainThreadOnly = aMainThreadOnly ;
}
void TextureClient : : ForceRemove ( bool sync )
{
if ( mActor & & mActor - > mDestroyed ) {
mActor = nullptr ;
}
if ( mValid & & mActor ) {
FinalizeOnIPDLThread ( ) ;
if ( mActor - > CanSend ( ) ) {
if ( sync | | GetFlags ( ) & TextureFlags : : DEALLOCATE_CLIENT ) {
mActor - > DestroySynchronously ( ) ;
} else {
mActor - > Destroy ( ) ;
}
}
}
MarkInvalid ( ) ;
2013-12-12 05:44:45 +04:00
}
2014-03-08 01:34:04 +04:00
bool TextureClient : : CopyToTextureClient ( TextureClient * aTarget ,
const gfx : : IntRect * aRect ,
const gfx : : IntPoint * aPoint )
{
MOZ_ASSERT ( IsLocked ( ) ) ;
MOZ_ASSERT ( aTarget - > IsLocked ( ) ) ;
2014-04-10 12:14:28 +04:00
if ( ! aTarget - > CanExposeDrawTarget ( ) | | ! CanExposeDrawTarget ( ) ) {
2014-03-08 01:34:04 +04:00
return false ;
}
2015-10-18 08:24:48 +03:00
RefPtr < DrawTarget > destinationTarget = aTarget - > BorrowDrawTarget ( ) ;
2015-03-09 22:48:20 +03:00
if ( ! destinationTarget ) {
gfxWarning ( ) < < " TextureClient::CopyToTextureClient (dest) failed in BorrowDrawTarget " ;
return false ;
}
2015-10-18 08:24:48 +03:00
RefPtr < DrawTarget > sourceTarget = BorrowDrawTarget ( ) ;
2015-03-09 22:48:20 +03:00
if ( ! sourceTarget ) {
gfxWarning ( ) < < " TextureClient::CopyToTextureClient (src) failed in BorrowDrawTarget " ;
return false ;
}
2015-10-18 08:24:48 +03:00
RefPtr < gfx : : SourceSurface > source = sourceTarget - > Snapshot ( ) ;
2014-03-08 01:34:04 +04:00
destinationTarget - > CopySurface ( source ,
aRect ? * aRect : gfx : : IntRect ( gfx : : IntPoint ( 0 , 0 ) , GetSize ( ) ) ,
aPoint ? * aPoint : gfx : : IntPoint ( 0 , 0 ) ) ;
return true ;
}
2015-10-15 18:53:37 +03:00
void
2015-11-20 18:55:26 +03:00
TextureClient : : Finalize ( )
{
MOZ_ASSERT ( ! IsLocked ( ) ) ;
// Always make a temporary strong reference to the actor before we use it,
// in case TextureChild::ActorDestroy might null mActor concurrently.
RefPtr < TextureChild > actor = mActor ;
if ( actor ) {
if ( actor - > mDestroyed ) {
actor = nullptr ;
return ;
}
// The actor has a raw pointer to us, actor->mTextureClient.
// Null it before RemoveTexture calls to avoid invalid actor->mTextureClient
// when calling TextureChild::ActorDestroy()
actor - > SetTextureClient ( nullptr ) ;
// `actor->mWaitForRecycle` may not be null, as we may be being called from setting
// this RefPtr to null! Clearing it here will double-Release() it.
// this will call ForceRemove in the right thread, using a sync proxy if needed
if ( actor - > GetForwarder ( ) ) {
actor - > GetForwarder ( ) - > RemoveTexture ( this ) ;
}
}
}
bool
TextureClient : : ShouldDeallocateInDestructor ( ) const
{
if ( ! IsAllocated ( ) ) {
return false ;
}
// If we're meant to be deallocated by the host,
// but we haven't been shared yet or
// TextureFlags::DEALLOCATE_CLIENT is set, then we should
// deallocate on the client instead.
return ! mShared | | ( GetFlags ( ) & TextureFlags : : DEALLOCATE_CLIENT ) ;
2015-10-15 18:53:37 +03:00
}
2014-12-18 21:32:45 +03:00
void
TextureClient : : PrintInfo ( std : : stringstream & aStream , const char * aPrefix )
{
aStream < < aPrefix ;
aStream < < nsPrintfCString ( " TextureClient (0x%p) " , this ) . get ( ) ;
AppendToString ( aStream , GetSize ( ) , " [size= " , " ] " ) ;
AppendToString ( aStream , GetFormat ( ) , " [format= " , " ] " ) ;
AppendToString ( aStream , mFlags , " [flags= " , " ] " ) ;
# ifdef MOZ_DUMP_PAINTING
if ( gfxPrefs : : LayersDumpTexture ( ) | | profiler_feature_active ( " layersdump " ) ) {
nsAutoCString pfx ( aPrefix ) ;
pfx + = " " ;
aStream < < " \n " < < pfx . get ( ) < < " Surface: " ;
2015-10-18 08:24:48 +03:00
RefPtr < gfx : : DataSourceSurface > dSurf = GetAsSurface ( ) ;
2014-12-18 21:32:45 +03:00
if ( dSurf ) {
aStream < < gfxUtils : : GetAsLZ4Base64Str ( dSurf ) . get ( ) ;
}
}
# endif
}
2015-11-20 18:55:26 +03:00
bool
ShmemTextureClient : : ToSurfaceDescriptor ( SurfaceDescriptor & aDescriptor )
{
MOZ_ASSERT ( IsValid ( ) ) ;
if ( ! IsAllocated ( ) | | GetFormat ( ) = = gfx : : SurfaceFormat : : UNKNOWN ) {
return false ;
}
aDescriptor = SurfaceDescriptorShmem ( mShmem , GetFormat ( ) ) ;
return true ;
}
2013-07-30 13:59:51 +04:00
bool
2015-11-20 18:55:26 +03:00
ShmemTextureClient : : Allocate ( uint32_t aSize )
2014-07-25 13:24:46 +04:00
{
2015-11-20 18:55:26 +03:00
MOZ_ASSERT ( mValid ) ;
if ( aSize > 0 ) {
SharedMemory : : SharedMemoryType memType = OptimalShmemType ( ) ;
mAllocated = GetAllocator ( ) - > AllocUnsafeShmem ( aSize , memType , & mShmem ) ;
}
return mAllocated ;
}
uint8_t *
ShmemTextureClient : : GetBuffer ( ) const
{
MOZ_ASSERT ( IsValid ( ) ) ;
if ( mAllocated ) {
return mShmem . get < uint8_t > ( ) ;
}
return nullptr ;
}
size_t
ShmemTextureClient : : GetBufferSize ( ) const
{
MOZ_ASSERT ( IsValid ( ) ) ;
return mShmem . Size < uint8_t > ( ) ;
}
ShmemTextureClient : : ShmemTextureClient ( ISurfaceAllocator * aAllocator ,
gfx : : SurfaceFormat aFormat ,
gfx : : BackendType aMoz2DBackend ,
TextureFlags aFlags )
: BufferTextureClient ( aAllocator , aFormat , aMoz2DBackend , aFlags )
, mAllocated ( false )
{
MOZ_COUNT_CTOR ( ShmemTextureClient ) ;
}
2014-12-09 21:19:29 +03:00
2015-11-20 18:55:26 +03:00
ShmemTextureClient : : ~ ShmemTextureClient ( )
{
MOZ_COUNT_DTOR ( ShmemTextureClient ) ;
if ( ShouldDeallocateInDestructor ( ) ) {
// if the buffer has never been shared we must deallocate it or ir would
// leak.
GetAllocator ( ) - > DeallocShmem ( mShmem ) ;
}
}
bool
MemoryTextureClient : : ToSurfaceDescriptor ( SurfaceDescriptor & aDescriptor )
{
MOZ_ASSERT ( IsValid ( ) ) ;
if ( ! IsAllocated ( ) | | GetFormat ( ) = = gfx : : SurfaceFormat : : UNKNOWN ) {
2013-07-30 13:59:51 +04:00
return false ;
}
2015-11-20 18:55:26 +03:00
aDescriptor = SurfaceDescriptorMemory ( reinterpret_cast < uintptr_t > ( mBuffer ) ,
GetFormat ( ) ) ;
return true ;
}
2013-12-05 22:39:22 +04:00
2015-11-20 18:55:26 +03:00
bool
MemoryTextureClient : : Allocate ( uint32_t aSize )
{
MOZ_ASSERT ( ! mBuffer ) ;
mBuffer = new ( fallible ) uint8_t [ aSize ] ;
if ( ! mBuffer ) {
NS_WARNING ( " Failed to allocate buffer " ) ;
2013-07-30 13:59:51 +04:00
return false ;
}
2015-11-20 18:55:26 +03:00
GfxMemoryImageReporter : : DidAlloc ( mBuffer ) ;
mBufSize = aSize ;
return true ;
}
2013-08-03 21:30:28 +04:00
2015-11-20 18:55:26 +03:00
MemoryTextureClient : : MemoryTextureClient ( ISurfaceAllocator * aAllocator ,
gfx : : SurfaceFormat aFormat ,
gfx : : BackendType aMoz2DBackend ,
TextureFlags aFlags )
: BufferTextureClient ( aAllocator , aFormat , aMoz2DBackend , aFlags )
, mBuffer ( nullptr )
, mBufSize ( 0 )
{
MOZ_COUNT_CTOR ( MemoryTextureClient ) ;
}
MemoryTextureClient : : ~ MemoryTextureClient ( )
{
MOZ_COUNT_DTOR ( MemoryTextureClient ) ;
if ( mBuffer & & ShouldDeallocateInDestructor ( ) ) {
// if the buffer has never been shared we must deallocate it or it would
// leak.
GfxMemoryImageReporter : : WillFree ( mBuffer ) ;
delete [ ] mBuffer ;
}
}
BufferTextureClient : : BufferTextureClient ( ISurfaceAllocator * aAllocator ,
gfx : : SurfaceFormat aFormat ,
gfx : : BackendType aMoz2DBackend ,
TextureFlags aFlags )
: TextureClient ( aAllocator , aFlags )
, mFormat ( aFormat )
, mBackend ( aMoz2DBackend )
, mOpenMode ( OpenMode : : OPEN_NONE )
, mLocked ( false )
{ }
BufferTextureClient : : ~ BufferTextureClient ( )
{ }
already_AddRefed < TextureClient >
BufferTextureClient : : CreateSimilar ( TextureFlags aFlags ,
TextureAllocationFlags aAllocFlags ) const
{
// This may return null
RefPtr < BufferTextureClient > newBufferTex = TextureClient : : CreateForRawBufferAccess (
mAllocator , mFormat , mSize , mBackend , mFlags | aFlags , aAllocFlags
) ;
return newBufferTex . forget ( ) ;
}
bool
BufferTextureClient : : AllocateForSurface ( gfx : : IntSize aSize , TextureAllocationFlags aFlags )
{
MOZ_ASSERT ( IsValid ( ) ) ;
MOZ_ASSERT ( mFormat ! = gfx : : SurfaceFormat : : YUV , " This textureClient cannot use YCbCr data " ) ;
MOZ_ASSERT ( aSize . width > 0 & & aSize . height > 0 ) ;
if ( aSize . width < = 0 | | aSize . height < = 0 ) {
gfxDebug ( ) < < " Asking for buffer of invalid size " < < aSize . width < < " x " < < aSize . height ;
return false ;
2013-07-30 13:59:51 +04:00
}
2015-11-20 18:55:26 +03:00
uint32_t bufSize = ImageDataSerializer : : ComputeMinBufferSize ( aSize , mFormat ) ;
if ( ! bufSize | | ! Allocate ( bufSize ) ) {
return false ;
}
if ( aFlags & ALLOC_CLEAR_BUFFER ) {
memset ( GetBuffer ( ) , 0 , bufSize ) ;
}
if ( aFlags & ALLOC_CLEAR_BUFFER_WHITE ) {
memset ( GetBuffer ( ) , 0xFF , bufSize ) ;
}
ImageDataSerializer serializer ( GetBuffer ( ) , GetBufferSize ( ) ) ;
serializer . InitializeBufferInfo ( aSize , mFormat ) ;
mSize = aSize ;
2013-07-30 13:59:51 +04:00
return true ;
}
2015-11-20 18:55:26 +03:00
gfx : : DrawTarget *
BufferTextureClient : : BorrowDrawTarget ( )
2014-12-13 04:50:47 +03:00
{
2015-11-20 18:55:26 +03:00
MOZ_ASSERT ( IsValid ( ) ) ;
MOZ_ASSERT ( NS_IsMainThread ( ) ) ;
MOZ_ASSERT ( mLocked , " BorrowDrawTarget should be called on locked textures only " ) ;
if ( ! mLocked ) {
2014-12-13 04:50:47 +03:00
return nullptr ;
}
2015-11-20 18:55:26 +03:00
if ( mDrawTarget ) {
mDrawTarget - > SetTransform ( Matrix ( ) ) ;
return mDrawTarget ;
}
ImageDataSerializer serializer ( GetBuffer ( ) , GetBufferSize ( ) ) ;
if ( ! serializer . IsValid ( ) ) {
gfxCriticalNote < < " Invalid serializer " < < IsValid ( ) < < " , " < < IsLocked ( ) < < " , " < < GetBufferSize ( ) ;
return nullptr ;
}
mDrawTarget = serializer . GetAsDrawTarget ( mBackend ) ;
if ( mDrawTarget ) {
return mDrawTarget ;
}
mDrawTarget = serializer . GetAsDrawTarget ( BackendType : : CAIRO ) ;
if ( ! mDrawTarget ) {
gfxCriticalNote < < " BorrowDrawTarget failure, original backend " < < ( int ) mBackend ;
}
return mDrawTarget ;
2014-12-13 04:50:47 +03:00
}
2015-11-20 18:55:26 +03:00
void
BufferTextureClient : : UpdateFromSurface ( gfx : : SourceSurface * aSurface )
2015-10-15 18:53:37 +03:00
{
2015-11-20 18:55:26 +03:00
ImageDataSerializer serializer ( GetBuffer ( ) , GetBufferSize ( ) ) ;
RefPtr < DataSourceSurface > surface = serializer . GetAsSurface ( ) ;
if ( ! surface ) {
gfxCriticalError ( ) < < " Failed to get serializer as surface! " ;
return ;
}
RefPtr < DataSourceSurface > srcSurf = aSurface - > GetDataSurface ( ) ;
if ( ! srcSurf ) {
gfxCriticalError ( ) < < " Failed to GetDataSurface in UpdateFromSurface. " ;
return ;
}
if ( surface - > GetSize ( ) ! = srcSurf - > GetSize ( ) | | surface - > GetFormat ( ) ! = srcSurf - > GetFormat ( ) ) {
gfxCriticalError ( ) < < " Attempt to update texture client from a surface with a different size or format! This: " < < surface - > GetSize ( ) < < " " < < surface - > GetFormat ( ) < < " Other: " < < aSurface - > GetSize ( ) < < " " < < aSurface - > GetFormat ( ) ;
return ;
}
DataSourceSurface : : MappedSurface sourceMap ;
DataSourceSurface : : MappedSurface destMap ;
if ( ! srcSurf - > Map ( DataSourceSurface : : READ , & sourceMap ) ) {
gfxCriticalError ( ) < < " Failed to map source surface for UpdateFromSurface. " ;
return ;
}
if ( ! surface - > Map ( DataSourceSurface : : WRITE , & destMap ) ) {
srcSurf - > Unmap ( ) ;
gfxCriticalError ( ) < < " Failed to map destination surface for UpdateFromSurface. " ;
return ;
2015-10-15 18:53:37 +03:00
}
2015-11-20 18:55:26 +03:00
for ( int y = 0 ; y < srcSurf - > GetSize ( ) . height ; y + + ) {
memcpy ( destMap . mData + destMap . mStride * y ,
sourceMap . mData + sourceMap . mStride * y ,
srcSurf - > GetSize ( ) . width * BytesPerPixel ( srcSurf - > GetFormat ( ) ) ) ;
}
srcSurf - > Unmap ( ) ;
surface - > Unmap ( ) ;
2015-10-15 18:53:37 +03:00
}
2015-10-15 18:53:33 +03:00
bool
2015-11-20 18:55:26 +03:00
BufferTextureClient : : Lock ( OpenMode aMode )
2015-10-15 18:53:33 +03:00
{
2015-11-20 18:55:26 +03:00
MOZ_ASSERT ( ! mLocked , " The TextureClient is already Locked! " ) ;
mOpenMode = aMode ;
mLocked = IsValid ( ) & & IsAllocated ( ) ; ;
return mLocked ;
}
void
BufferTextureClient : : Unlock ( )
{
MOZ_ASSERT ( mLocked , " The TextureClient is already Unlocked! " ) ;
mLocked = false ;
if ( ! mDrawTarget ) {
return ;
}
// see the comment on TextureClient::BorrowDrawTarget.
// This DrawTarget is internal to the TextureClient and is only exposed to the
// outside world between Lock() and Unlock(). This assertion checks that no outside
// reference remains by the time Unlock() is called.
MOZ_ASSERT ( mDrawTarget - > refCount ( ) = = 1 ) ;
if ( mReadbackSink ) {
RefPtr < SourceSurface > snapshot = mDrawTarget - > Snapshot ( ) ;
RefPtr < DataSourceSurface > dataSurf = snapshot - > GetDataSurface ( ) ;
mReadbackSink - > ProcessReadback ( dataSurf ) ;
}
mDrawTarget - > Flush ( ) ;
}
bool
BufferTextureClient : : UpdateYCbCr ( const PlanarYCbCrData & aData )
{
MOZ_ASSERT ( mLocked ) ;
MOZ_ASSERT ( mFormat = = gfx : : SurfaceFormat : : YUV , " This textureClient can only use YCbCr data " ) ;
MOZ_ASSERT ( ! IsImmutable ( ) ) ;
MOZ_ASSERT ( IsValid ( ) ) ;
MOZ_ASSERT ( aData . mCbSkip = = aData . mCrSkip ) ;
YCbCrImageDataSerializer serializer ( GetBuffer ( ) , GetBufferSize ( ) ) ;
MOZ_ASSERT ( serializer . IsValid ( ) ) ;
if ( ! serializer . CopyData ( aData . mYChannel , aData . mCbChannel , aData . mCrChannel ,
aData . mYSize , aData . mYStride ,
aData . mCbCrSize , aData . mCbCrStride ,
aData . mYSkip , aData . mCbSkip ) ) {
NS_WARNING ( " Failed to copy image data! " ) ;
2015-10-15 18:53:33 +03:00
return false ;
}
2015-11-20 18:55:26 +03:00
if ( TextureRequiresLocking ( mFlags ) ) {
// We don't have support for proper locking yet, so we'll
// have to be immutable instead.
MarkImmutable ( ) ;
2015-10-15 18:53:33 +03:00
}
2015-11-20 18:55:26 +03:00
return true ;
}
2015-10-15 18:53:33 +03:00
2015-11-20 18:55:26 +03:00
bool
BufferTextureClient : : AllocateForYCbCr ( gfx : : IntSize aYSize ,
gfx : : IntSize aCbCrSize ,
StereoMode aStereoMode )
{
MOZ_ASSERT ( IsValid ( ) ) ;
size_t bufSize = YCbCrImageDataSerializer : : ComputeMinBufferSize ( aYSize ,
aCbCrSize ) ;
if ( ! bufSize | | ! Allocate ( bufSize ) ) {
return false ;
2015-10-15 18:53:33 +03:00
}
2015-11-20 18:55:26 +03:00
YCbCrImageDataSerializer serializer ( GetBuffer ( ) , GetBufferSize ( ) ) ;
serializer . InitializeBufferInfo ( aYSize ,
aCbCrSize ,
aStereoMode ) ;
mSize = aYSize ;
2015-10-15 18:53:33 +03:00
return true ;
}
2015-11-20 18:55:26 +03:00
uint8_t *
BufferTextureClient : : GetLockedData ( ) const
{
MOZ_ASSERT ( IsLocked ( ) ) ;
ImageDataSerializer serializer ( GetBuffer ( ) , GetBufferSize ( ) ) ;
MOZ_ASSERT ( serializer . IsValid ( ) ) ;
return serializer . GetData ( ) ;
}
already_AddRefed < SyncObject >
SyncObject : : CreateSyncObject ( SyncHandle aHandle )
{
if ( ! aHandle ) {
return nullptr ;
}
# ifdef XP_WIN
return MakeAndAddRef < SyncObjectD3D11 > ( aHandle ) ;
# else
MOZ_ASSERT_UNREACHABLE ( ) ;
return nullptr ;
# endif
}
2015-07-13 18:25:42 +03:00
} // namespace layers
} // namespace mozilla