import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1250873 - Rename HasInternalBuffer into HasIntermediateBuffer in layers. r=sotaro (578235105f)
- Bug 1256045 - Add a null-check in BufferTextureHost::EnsureWrappingTextureSource. r=jnicol (943c73559d)
- Bug 1251726 - Check if Compositor is set r=nical (550d5b0164)
- Bug 1251427 - Require a full update when a TextureHost switches from a TextureSource to another. r=sotaro (bc59ac4cd7)
- Bug 1256693 - ISurfaceAllocator cleanup. r=sotaro (098e824d4d)
- Bug 1257939 - initialize BGRX alpha channel to opaque when clearing and ignore uninitialized alpha in texture clients. r=mchang (73d778496f)
- more of reapply Bug 1200595 - Consolidate the TextureClient's destruction logic (74517415ed)
- Bug 1256693 - Refer to ClientIPCAllocator instead of ISurfaceAllocator where it makes sense. r=sotaro (e81f2dd923)
- Bug 1236112 - Block on d3d9 video frames to complete before returning them from the decoder. r=cpearce (25114bb3c4)
- Bug 1196409 - Disable D3D11-DXVA for resolutions not supported in hardware. r=jya (3007b1ebff)
- Bug 1196411 - Disable DXVA on 60fps 1080p videos for AMD cards that can't decode quick enough. r=jya (9f8f67e12b)
- Bug 1200775 - Check intel specific h264 decoder when checking for DXVA support. r=cpearce (e7bcbb10be)
- Bug 1257013 - Part 1: Use readback to synchronize d3d9 video. r=cpearce,Bas (d247a9bed6)
- Bug 1257013 - Part 2: Use readback to synchronize d3d11 video. r=cpearce,Bas (43883c1607)
- missing bit of Bug 1206568: P2 (58de11b22f)
- Bug 1239093 - Add pref to allow overriding of hardcoded DXVA blacklist. r=jrmuizel (dfd5e57c2f)
- Bug 1217185: To allow for sandboxing, use null HWNDs when creating the D3D device for video decoding. r=mattwoodrow (0c96e66a47)
- Bug 1200775 - Followup to fix typo and indent issues (b1d1c76788)
- bits of  Bug 1207245 - part 3 (52a1939b74)
- Bug 1224199 - Don't make the TextureClient wait for compositor recycle if the GLContext is shutting down - r=nical (9a0081f217)
- more of Bug 1200595 (047201fd60)
- Bug 1253094, part 2 - Stop using DebugOnly for class/struct members in gfx/. r=Bas (bab6569366)
This commit is contained in:
2024-02-01 10:25:42 +08:00
parent 0c05a61d5f
commit ca19b65a80
81 changed files with 1159 additions and 870 deletions
+2 -1
View File
@@ -48,6 +48,7 @@
#include "TimeUnits.h"
#include "VideoSegment.h"
#include "VideoUtils.h"
#include "gfxPrefs.h"
namespace mozilla {
@@ -2442,7 +2443,7 @@ MediaDecoderStateMachine::CheckFrameValidity(VideoData* aData)
MOZ_ASSERT(OnTaskQueue());
// Update corrupt-frames statistics
if (aData->mImage && !aData->mImage->IsValid()) {
if (aData->mImage && !aData->mImage->IsValid() && !gfxPrefs::HardwareVideoDecodingForceEnabled()) {
FrameStatistics& frameStats = *mFrameStats;
frameStats.NotifyCorruptFrame();
// If more than 10% of the last 30 frames have been corrupted, then try disabling
+262 -23
View File
@@ -37,6 +37,40 @@ const GUID MF_XVP_PLAYBACK_MODE =
DEFINE_GUID(MF_LOW_LATENCY,
0x9c27891a, 0xed7a, 0x40e1, 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee);
// R600, R700, Evergreen and Cayman AMD cards. These support DXVA via UVD3 or earlier, and don't
// handle 1080p60 well.
static const DWORD sAMDPreUVD4[] = {
0x9400, 0x9401, 0x9402, 0x9403, 0x9405, 0x940a, 0x940b, 0x940f, 0x94c0, 0x94c1, 0x94c3, 0x94c4, 0x94c5,
0x94c6, 0x94c7, 0x94c8, 0x94c9, 0x94cb, 0x94cc, 0x94cd, 0x9580, 0x9581, 0x9583, 0x9586, 0x9587, 0x9588,
0x9589, 0x958a, 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 0x9500, 0x9501, 0x9504, 0x9505, 0x9506, 0x9507,
0x9508, 0x9509, 0x950f, 0x9511, 0x9515, 0x9517, 0x9519, 0x95c0, 0x95c2, 0x95c4, 0x95c5, 0x95c6, 0x95c7,
0x95c9, 0x95cc, 0x95cd, 0x95ce, 0x95cf, 0x9590, 0x9591, 0x9593, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599,
0x959b, 0x9610, 0x9611, 0x9612, 0x9613, 0x9614, 0x9615, 0x9616, 0x9710, 0x9711, 0x9712, 0x9713, 0x9714,
0x9715, 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9446, 0x944a, 0x944b, 0x944c, 0x944e, 0x9450, 0x9452,
0x9456, 0x945a, 0x945b, 0x945e, 0x9460, 0x9462, 0x946a, 0x946b, 0x947a, 0x947b, 0x9480, 0x9487, 0x9488,
0x9489, 0x948a, 0x948f, 0x9490, 0x9491, 0x9495, 0x9498, 0x949c, 0x949e, 0x949f, 0x9540, 0x9541, 0x9542,
0x954e, 0x954f, 0x9552, 0x9553, 0x9555, 0x9557, 0x955f, 0x94a0, 0x94a1, 0x94a3, 0x94b1, 0x94b3, 0x94b4,
0x94b5, 0x94b9, 0x68e0, 0x68e1, 0x68e4, 0x68e5, 0x68e8, 0x68e9, 0x68f1, 0x68f2, 0x68f8, 0x68f9, 0x68fa,
0x68fe, 0x68c0, 0x68c1, 0x68c7, 0x68c8, 0x68c9, 0x68d8, 0x68d9, 0x68da, 0x68de, 0x68a0, 0x68a1, 0x68a8,
0x68a9, 0x68b0, 0x68b8, 0x68b9, 0x68ba, 0x68be, 0x68bf, 0x6880, 0x6888, 0x6889, 0x688a, 0x688c, 0x688d,
0x6898, 0x6899, 0x689b, 0x689e, 0x689c, 0x689d, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806, 0x9807, 0x9808,
0x9809, 0x980a, 0x9640, 0x9641, 0x9647, 0x9648, 0x964a, 0x964b, 0x964c, 0x964e, 0x964f, 0x9642, 0x9643,
0x9644, 0x9645, 0x9649, 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6726, 0x6727, 0x6728, 0x6729,
0x6738, 0x6739, 0x673e, 0x6740, 0x6741, 0x6742, 0x6743, 0x6744, 0x6745, 0x6746, 0x6747, 0x6748, 0x6749,
0x674a, 0x6750, 0x6751, 0x6758, 0x6759, 0x675b, 0x675d, 0x675f, 0x6840, 0x6841, 0x6842, 0x6843, 0x6849,
0x6850, 0x6858, 0x6859, 0x6760, 0x6761, 0x6762, 0x6763, 0x6764, 0x6765, 0x6766, 0x6767, 0x6768, 0x6770,
0x6771, 0x6772, 0x6778, 0x6779, 0x677b, 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707,
0x6708, 0x6709, 0x6718, 0x6719, 0x671c, 0x671d, 0x671f, 0x9900, 0x9901, 0x9903, 0x9904, 0x9905, 0x9906,
0x9907, 0x9908, 0x9909, 0x990a, 0x990b, 0x990c, 0x990d, 0x990e, 0x990f, 0x9910, 0x9913, 0x9917, 0x9918,
0x9919, 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998, 0x9999, 0x999a, 0x999b,
0x999c, 0x999d, 0x99a0, 0x99a2, 0x99a4
};
// The size we use for our synchronization surface.
// 16x16 is the size recommended by Microsoft (in the D3D9ExDXGISharedSurf sample) that works
// best to avoid driver bugs.
static const uint32_t kSyncSurfaceSize = 16;
namespace mozilla {
using layers::Image;
@@ -63,7 +97,7 @@ public:
ImageContainer* aContainer,
Image** aOutImage) override;
virtual bool SupportsConfig(IMFMediaType* aType) override;
bool SupportsConfig(IMFMediaType* aType, float aFramerate) override;
private:
RefPtr<IDirect3D9Ex> mD3D9;
@@ -71,8 +105,11 @@ private:
RefPtr<IDirect3DDeviceManager9> mDeviceManager;
RefPtr<D3D9RecycleAllocator> mTextureClientAllocator;
RefPtr<IDirectXVideoDecoderService> mDecoderService;
RefPtr<IDirect3DSurface9> mSyncSurface;
GUID mDecoderGUID;
UINT32 mResetToken;
bool mFirstFrame;
bool mIsAMDPreUVD4;
};
void GetDXVA2ExtendedFormatFromMFMediaType(IMFMediaType *pType,
@@ -140,26 +177,39 @@ static const GUID DXVA2_ModeH264_E = {
0x1b81be68, 0xa0c7, 0x11d3, { 0xb9, 0x84, 0x00, 0xc0, 0x4f, 0x2e, 0x73, 0xc5 }
};
static const GUID DXVA2_Intel_ModeH264_E = {
0x604F8E68, 0x4951, 0x4c54, { 0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6 }
};
// This tests if a DXVA video decoder can be created for the given media type/resolution.
// It uses the same decoder device (DXVA2_ModeH264_E - DXVA2_ModeH264_VLD_NoFGT) as the H264
// decoder MFT provided by windows (CLSID_CMSH264DecoderMFT) uses, so we can use it to determine
// if the MFT will use software fallback or not.
bool
D3D9DXVA2Manager::SupportsConfig(IMFMediaType* aType)
D3D9DXVA2Manager::SupportsConfig(IMFMediaType* aType, float aFramerate)
{
DXVA2_VideoDesc desc;
HRESULT hr = ConvertMFTypeToDXVAType(aType, &desc);
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
// AMD cards with UVD3 or earlier perform poorly trying to decode 1080p60 in hardware,
// so use software instead. Pick 45 as an arbitrary upper bound for the framerate we can
// handle.
if (mIsAMDPreUVD4 &&
(desc.SampleWidth >= 1920 || desc.SampleHeight >= 1088) &&
aFramerate > 45) {
return false;
}
UINT configCount;
DXVA2_ConfigPictureDecode* configs = nullptr;
hr = mDecoderService->GetDecoderConfigurations(DXVA2_ModeH264_E, &desc, nullptr, &configCount, &configs);
hr = mDecoderService->GetDecoderConfigurations(mDecoderGUID, &desc, nullptr, &configCount, &configs);
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
RefPtr<IDirect3DSurface9> surface;
hr = mDecoderService->CreateSurface(desc.SampleWidth, desc.SampleHeight, 0, (D3DFORMAT)MAKEFOURCC('N', 'V', '1', '2'),
D3DPOOL_DEFAULT, 0, DXVA2_VideoDecoderRenderTarget,
surface.StartAssignment(), NULL);
D3DPOOL_DEFAULT, 0, DXVA2_VideoDecoderRenderTarget,
surface.StartAssignment(), NULL);
if (!SUCCEEDED(hr)) {
CoTaskMemFree(configs);
return false;
@@ -168,7 +218,7 @@ D3D9DXVA2Manager::SupportsConfig(IMFMediaType* aType)
for (UINT i = 0; i < configCount; i++) {
RefPtr<IDirectXVideoDecoder> decoder;
IDirect3DSurface9* surfaces = surface;
hr = mDecoderService->CreateVideoDecoder(DXVA2_ModeH264_E, &desc, &configs[i], &surfaces, 1, decoder.StartAssignment());
hr = mDecoderService->CreateVideoDecoder(mDecoderGUID, &desc, &configs[i], &surfaces, 1, decoder.StartAssignment());
if (SUCCEEDED(hr) && decoder) {
CoTaskMemFree(configs);
return true;
@@ -181,6 +231,7 @@ D3D9DXVA2Manager::SupportsConfig(IMFMediaType* aType)
D3D9DXVA2Manager::D3D9DXVA2Manager()
: mResetToken(0)
, mFirstFrame(true)
, mIsAMDPreUVD4(false)
{
MOZ_COUNT_CTOR(D3D9DXVA2Manager);
MOZ_ASSERT(NS_IsMainThread());
@@ -235,21 +286,23 @@ D3D9DXVA2Manager::Init(nsACString& aFailureReason)
return hr;
}
// Create D3D9DeviceEx.
// Create D3D9DeviceEx. We pass null HWNDs here even though the documentation
// suggests that one of them should not be. At this point in time Chromium
// does the same thing for video acceleration.
D3DPRESENT_PARAMETERS params = {0};
params.BackBufferWidth = 1;
params.BackBufferHeight = 1;
params.BackBufferFormat = D3DFMT_UNKNOWN;
params.BackBufferCount = 1;
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
params.hDeviceWindow = ::GetShellWindow();
params.hDeviceWindow = nullptr;
params.Windowed = TRUE;
params.Flags = D3DPRESENTFLAG_VIDEO;
RefPtr<IDirect3DDevice9Ex> device;
hr = d3d9Ex->CreateDeviceEx(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
::GetShellWindow(),
nullptr,
D3DCREATE_FPU_PRESERVE |
D3DCREATE_MULTITHREADED |
D3DCREATE_MIXED_VERTEXPROCESSING,
@@ -292,20 +345,31 @@ D3D9DXVA2Manager::Init(nsACString& aFailureReason)
HANDLE deviceHandle;
RefPtr<IDirectXVideoDecoderService> decoderService;
hr = deviceManager->OpenDeviceHandle(&deviceHandle);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("IDirect3DDeviceManager9::OpenDeviceHandle failed with error %X", hr);
return hr;
}
hr = deviceManager->GetVideoService(deviceHandle, IID_PPV_ARGS(decoderService.StartAssignment()));
deviceManager->CloseDeviceHandle(deviceHandle);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("IDirectXVideoDecoderServer::GetVideoService failed with error %X", hr);
return hr;
}
UINT deviceCount;
GUID* decoderDevices = nullptr;
hr = decoderService->GetDecoderDeviceGuids(&deviceCount, &decoderDevices);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("IDirectXVideoDecoderServer::GetDecoderDeviceGuids failed with error %X", hr);
return hr;
}
bool found = false;
for (UINT i = 0; i < deviceCount; i++) {
if (decoderDevices[i] == DXVA2_ModeH264_E) {
if (decoderDevices[i] == DXVA2_ModeH264_E ||
decoderDevices[i] == DXVA2_Intel_ModeH264_E) {
mDecoderGUID = decoderDevices[i];
found = true;
break;
}
@@ -313,15 +377,40 @@ D3D9DXVA2Manager::Init(nsACString& aFailureReason)
CoTaskMemFree(decoderDevices);
if (!found) {
aFailureReason.AssignLiteral("Failed to find an appropriate decoder GUID");
return E_FAIL;
}
D3DADAPTER_IDENTIFIER9 adapter;
hr = d3d9Ex->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &adapter);
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("IDirect3D9Ex::GetAdapterIdentifier failed with error %X", hr);
return hr;
}
if (adapter.VendorId == 0x1022 &&
!Preferences::GetBool("media.wmf.skip-blacklist", false)) {
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sAMDPreUVD4); i++) {
if (adapter.DeviceId == sAMDPreUVD4[i]) {
mIsAMDPreUVD4 = true;
break;
}
}
}
RefPtr<IDirect3DSurface9> syncSurf;
hr = device->CreateRenderTarget(kSyncSurfaceSize, kSyncSurfaceSize,
D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE,
0, TRUE, getter_AddRefs(syncSurf), NULL);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
mDecoderService = decoderService;
mResetToken = resetToken;
mD3D9 = d3d9Ex;
mDevice = device;
mDeviceManager = deviceManager;
mSyncSurface = syncSurf;
mTextureClientAllocator = new D3D9RecycleAllocator(layers::ImageBridgeChild::GetSingleton(),
mDevice);
@@ -347,11 +436,24 @@ D3D9DXVA2Manager::CopyToImage(IMFSample* aSample,
getter_AddRefs(surface));
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
RefPtr<D3D9SurfaceImage> image = new D3D9SurfaceImage(mFirstFrame);
RefPtr<D3D9SurfaceImage> image = new D3D9SurfaceImage();
hr = image->AllocateAndCopy(mTextureClientAllocator, surface, aRegion);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
mFirstFrame = false;
RefPtr<IDirect3DSurface9> sourceSurf = image->GetD3D9Surface();
// Copy a small rect into our sync surface, and then map it
// to block until decoding/color conversion completes.
RECT copyRect = { 0, 0, kSyncSurfaceSize, kSyncSurfaceSize };
hr = mDevice->StretchRect(sourceSurf, &copyRect, mSyncSurface, &copyRect, D3DTEXF_NONE);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
D3DLOCKED_RECT lockedRect;
hr = mSyncSurface->LockRect(&lockedRect, NULL, D3DLOCK_READONLY);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = mSyncSurface->UnlockRect();
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
image.forget(aOutImage);
return S_OK;
@@ -408,6 +510,8 @@ public:
bool IsD3D11() override { return true; }
bool SupportsConfig(IMFMediaType* aType, float aFramerate) override;
private:
HRESULT CreateFormatConverter();
@@ -419,15 +523,65 @@ private:
RefPtr<IMFDXGIDeviceManager> mDXGIDeviceManager;
RefPtr<MFTDecoder> mTransform;
RefPtr<D3D11RecycleAllocator> mTextureClientAllocator;
RefPtr<ID3D11Texture2D> mSyncSurface;
GUID mDecoderGUID;
uint32_t mWidth;
uint32_t mHeight;
UINT mDeviceManagerToken;
bool mIsAMDPreUVD4;
};
bool
D3D11DXVA2Manager::SupportsConfig(IMFMediaType* aType, float aFramerate)
{
RefPtr<ID3D11VideoDevice> videoDevice;
HRESULT hr = mDevice->QueryInterface(static_cast<ID3D11VideoDevice**>(getter_AddRefs(videoDevice)));
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
D3D11_VIDEO_DECODER_DESC desc;
desc.Guid = mDecoderGUID;
UINT32 width = 0;
UINT32 height = 0;
hr = MFGetAttributeSize(aType, MF_MT_FRAME_SIZE, &width, &height);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
desc.SampleWidth = width;
desc.SampleHeight = height;
desc.OutputFormat = DXGI_FORMAT_NV12;
// AMD cards with UVD3 or earlier perform poorly trying to decode 1080p60 in hardware,
// so use software instead. Pick 45 as an arbitrary upper bound for the framerate we can
// handle.
if (mIsAMDPreUVD4 &&
(desc.SampleWidth >= 1920 || desc.SampleHeight >= 1088) &&
aFramerate > 45) {
return false;
}
UINT configCount = 0;
hr = videoDevice->GetVideoDecoderConfigCount(&desc, &configCount);
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
for (UINT i = 0; i < configCount; i++) {
D3D11_VIDEO_DECODER_CONFIG config;
hr = videoDevice->GetVideoDecoderConfig(&desc, i, &config);
if (SUCCEEDED(hr)) {
RefPtr<ID3D11VideoDecoder> decoder;
hr = videoDevice->CreateVideoDecoder(&desc, &config, decoder.StartAssignment());
if (SUCCEEDED(hr) && decoder) {
return true;
}
}
}
return false;
}
D3D11DXVA2Manager::D3D11DXVA2Manager()
: mWidth(0)
, mHeight(0)
, mDeviceManagerToken(0)
, mIsAMDPreUVD4(false)
{
}
@@ -484,6 +638,87 @@ D3D11DXVA2Manager::Init(nsACString& aFailureReason)
return hr;
}
RefPtr<ID3D11VideoDevice> videoDevice;
hr = mDevice->QueryInterface(static_cast<ID3D11VideoDevice**>(getter_AddRefs(videoDevice)));
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("QI to ID3D11VideoDevice failed with code %X", hr);
return hr;
}
bool found = false;
UINT profileCount = videoDevice->GetVideoDecoderProfileCount();
for (UINT i = 0; i < profileCount; i++) {
GUID id;
hr = videoDevice->GetVideoDecoderProfile(i, &id);
if (SUCCEEDED(hr) && (id == DXVA2_ModeH264_E || id == DXVA2_Intel_ModeH264_E)) {
mDecoderGUID = id;
found = true;
break;
}
}
if (!found) {
aFailureReason.AssignLiteral("Failed to find an appropriate decoder GUID");
return E_FAIL;
}
BOOL nv12Support = false;
hr = videoDevice->CheckVideoDecoderFormat(&mDecoderGUID, DXGI_FORMAT_NV12, &nv12Support);
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("CheckVideoDecoderFormat failed with code %X", hr);
return hr;
}
if (!nv12Support) {
aFailureReason.AssignLiteral("Decoder doesn't support NV12 surfaces");
return E_FAIL;
}
RefPtr<IDXGIDevice> dxgiDevice;
hr = mDevice->QueryInterface(static_cast<IDXGIDevice**>(getter_AddRefs(dxgiDevice)));
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("QI to IDXGIDevice failed with code %X", hr);
return hr;
}
RefPtr<IDXGIAdapter> adapter;
hr = dxgiDevice->GetAdapter(adapter.StartAssignment());
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("IDXGIDevice::GetAdapter failed with code %X", hr);
return hr;
}
DXGI_ADAPTER_DESC adapterDesc;
hr = adapter->GetDesc(&adapterDesc);
if (!SUCCEEDED(hr)) {
aFailureReason = nsPrintfCString("IDXGIAdapter::GetDesc failed with code %X", hr);
return hr;
}
if (adapterDesc.VendorId == 0x1022 &&
!Preferences::GetBool("media.wmf.skip-blacklist", false)) {
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sAMDPreUVD4); i++) {
if (adapterDesc.DeviceId == sAMDPreUVD4[i]) {
mIsAMDPreUVD4 = true;
break;
}
}
}
D3D11_TEXTURE2D_DESC desc;
desc.Width = kSyncSurfaceSize;
desc.Height = kSyncSurfaceSize;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
hr = mDevice->CreateTexture2D(&desc, NULL, getter_AddRefs(mSyncSurface));
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
mTextureClientAllocator = new D3D11RecycleAllocator(layers::ImageBridgeChild::GetSingleton(),
mDevice);
mTextureClientAllocator->SetMaxPoolSize(5);
@@ -535,18 +770,22 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
hr = CreateOutputSample(sample, texture);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
RefPtr<IDXGIKeyedMutex> keyedMutex;
hr = texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(getter_AddRefs(keyedMutex)));
NS_ENSURE_TRUE(SUCCEEDED(hr) && keyedMutex, hr);
hr = keyedMutex->AcquireSync(0, INFINITE);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = mTransform->Output(&sample);
keyedMutex->ReleaseSync(0);
RefPtr<ID3D11DeviceContext> ctx;
mDevice->GetImmediateContext(getter_AddRefs(ctx));
// Copy a small rect into our sync surface, and then map it
// to block until decoding/color conversion completes.
D3D11_BOX rect = { 0, 0, 0, kSyncSurfaceSize, kSyncSurfaceSize, 1 };
ctx->CopySubresourceRegion(mSyncSurface, 0, 0, 0, 0, texture, 0, &rect);
D3D11_MAPPED_SUBRESOURCE mapped;
hr = ctx->Map(mSyncSurface, 0, D3D11_MAP_READ, 0, &mapped);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
ctx->Unmap(mSyncSurface, 0);
image.forget(aOutImage);
return S_OK;
+1 -1
View File
@@ -44,7 +44,7 @@ public:
virtual ~DXVA2Manager();
virtual bool SupportsConfig(IMFMediaType* aType) { return true; }
virtual bool SupportsConfig(IMFMediaType* aType, float aFramerate) = 0;
protected:
Mutex mLock;
@@ -305,6 +305,8 @@ WMFVideoMFTManager::Input(MediaRawData* aSample)
&mLastInput);
NS_ENSURE_TRUE(SUCCEEDED(hr) && mLastInput != nullptr, hr);
mLastDuration = aSample->mDuration;
// Forward sample data to the decoder.
return mDecoder->Input(mLastInput);
}
@@ -328,7 +330,11 @@ WMFVideoMFTManager::MaybeToggleDXVA(IMFMediaType* aType)
return false;
}
if (mDXVA2Manager->SupportsConfig(aType)) {
// Assume the current samples duration is representative for the
// entire video.
float framerate = 1000000.0 / mLastDuration;
if (mDXVA2Manager->SupportsConfig(aType, framerate)) {
if (!mUseHwAccel) {
// DXVA disabled, but supported for this resolution
ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager());
@@ -77,6 +77,7 @@ private:
nsAutoPtr<DXVA2Manager> mDXVA2Manager;
RefPtr<IMFSample> mLastInput;
float mLastDuration;
const bool mDXVAEnabled;
const layers::LayersBackend mLayersBackend;
+1 -1
View File
@@ -1256,7 +1256,7 @@ public:
CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
static already_AddRefed<DrawTarget>
CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
static already_AddRefed<ScaledFont>
CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
+2 -2
View File
@@ -896,10 +896,10 @@ VerifyRGBXFormat(uint8_t* aData, const IntSize &aSize, const int32_t aStride, Su
#endif
void
DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat)
DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized)
{
MOZ_ASSERT((aFormat != SurfaceFormat::B8G8R8X8) ||
VerifyRGBXFormat(aData, aSize, aStride, aFormat));
aUninitialized || VerifyRGBXFormat(aData, aSize, aStride, aFormat));
SkBitmap bitmap;
bitmap.setInfo(MakeSkiaImageInfo(aSize, aFormat), aStride);
+1 -1
View File
@@ -111,7 +111,7 @@ public:
virtual void *GetNativeSurface(NativeSurfaceType aType) override;
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
#ifdef USE_SKIA_GPU
bool InitWithGrContext(GrContext* aGrContext,
+3 -2
View File
@@ -395,7 +395,8 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat)
SurfaceFormat aFormat,
bool aUninitialized)
{
MOZ_ASSERT(aData);
if (!AllowedSurfaceSize(aSize)) {
@@ -411,7 +412,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
{
RefPtr<DrawTargetSkia> newTarget;
newTarget = new DrawTargetSkia();
newTarget->Init(aData, aSize, aStride, aFormat);
newTarget->Init(aData, aSize, aStride, aFormat, aUninitialized);
retVal = newTarget;
break;
}
+4 -2
View File
@@ -288,7 +288,7 @@ ChooseBufferBits(const SurfaceCaps& caps,
SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
: mType(type)
, mGL(gl)
@@ -304,7 +304,9 @@ SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
SurfaceFactory::~SurfaceFactory()
{
while (!mRecycleTotalPool.empty()) {
StopRecycling(*mRecycleTotalPool.begin());
RefPtr<layers::SharedSurfaceTextureClient> tex = *mRecycleTotalPool.begin();
StopRecycling(tex);
tex->CancelWaitForCompositorRecycle();
}
MOZ_RELEASE_ASSERT(mRecycleTotalPool.empty());
+6 -4
View File
@@ -39,7 +39,7 @@ class DrawTarget;
} // namespace gfx
namespace layers {
class ISurfaceAllocator;
class ClientIPCAllocator;
class SharedSurfaceTextureClient;
enum class TextureFlags : uint32_t;
class SurfaceDescriptor;
@@ -68,7 +68,9 @@ protected:
bool mIsLocked;
bool mIsProducerAcquired;
bool mIsConsumerAcquired;
DebugOnly<nsIThread* const> mOwningThread;
#ifdef DEBUG
nsIThread* const mOwningThread;
#endif
SharedSurface(SharedSurfaceType type,
AttachmentType attachType,
@@ -267,7 +269,7 @@ public:
const SharedSurfaceType mType;
GLContext* const mGL;
const SurfaceCaps mCaps;
const RefPtr<layers::ISurfaceAllocator> mAllocator;
const RefPtr<layers::ClientIPCAllocator> mAllocator;
const layers::TextureFlags mFlags;
const GLFormats mFormats;
Mutex mMutex;
@@ -278,7 +280,7 @@ protected:
RefSet<layers::SharedSurfaceTextureClient> mRecycleTotalPool;
SurfaceFactory(SharedSurfaceType type, GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags);
public:
+2 -2
View File
@@ -321,7 +321,7 @@ SharedSurface_ANGLEShareHandle::ReadbackBySharedHandle(gfx::DataSourceSurface* o
/*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
{
GLLibraryEGL* egl = &sEGLLibrary;
@@ -341,7 +341,7 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags,
GLLibraryEGL* egl,
EGLConfig config)
+2 -2
View File
@@ -89,12 +89,12 @@ protected:
public:
static UniquePtr<SurfaceFactory_ANGLEShareHandle> Create(GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags);
protected:
SurfaceFactory_ANGLEShareHandle(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags, GLLibraryEGL* egl,
EGLConfig config);
+2 -2
View File
@@ -383,7 +383,7 @@ SharedSurface_D3D11Interop::ToSurfaceDescriptor(layers::SurfaceDescriptor* const
/*static*/ UniquePtr<SurfaceFactory_D3D11Interop>
SurfaceFactory_D3D11Interop::Create(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
{
WGLLibrary* wgl = &sWGLLib;
@@ -404,7 +404,7 @@ SurfaceFactory_D3D11Interop::Create(GLContext* gl, const SurfaceCaps& caps,
SurfaceFactory_D3D11Interop::SurfaceFactory_D3D11Interop(GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags,
const RefPtr<DXGLDevice>& dxgl)
: SurfaceFactory(SharedSurfaceType::DXGLInterop2, gl, caps, allocator, flags)
+2 -2
View File
@@ -89,12 +89,12 @@ public:
static UniquePtr<SurfaceFactory_D3D11Interop> Create(GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags);
protected:
SurfaceFactory_D3D11Interop(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags,
const RefPtr<DXGLDevice>& dxgl);
+1 -1
View File
@@ -188,7 +188,7 @@ SharedSurface_EGLImage::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surfa
/*static*/ UniquePtr<SurfaceFactory_EGLImage>
SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
{
EGLContext context = GLContextEGL::Cast(prodGL)->mContext;
+2 -2
View File
@@ -93,14 +93,14 @@ public:
// Fallible:
static UniquePtr<SurfaceFactory_EGLImage> Create(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags);
protected:
const EGLContext mContext;
SurfaceFactory_EGLImage(GLContext* prodGL, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags,
EGLContext context)
: SurfaceFactory(SharedSurfaceType::EGLImageShare, prodGL, caps, allocator, flags)
+1 -1
View File
@@ -149,7 +149,7 @@ class SurfaceFactory_GLTexture
public:
SurfaceFactory_GLTexture(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
: SurfaceFactory(SharedSurfaceType::SharedGLTexture, prodGL, caps, allocator, flags)
{
+1 -1
View File
@@ -120,7 +120,7 @@ SharedSurface_GLXDrawable::ReadbackBySharedHandle(gfx::DataSourceSurface* out_su
UniquePtr<SurfaceFactory_GLXDrawable>
SurfaceFactory_GLXDrawable::Create(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
{
MOZ_ASSERT(caps.alpha, "GLX surfaces require an alpha channel!");
+2 -2
View File
@@ -49,14 +49,14 @@ class SurfaceFactory_GLXDrawable
public:
static UniquePtr<SurfaceFactory_GLXDrawable> Create(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags);
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
private:
SurfaceFactory_GLXDrawable(GLContext* prodGL, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
: SurfaceFactory(SharedSurfaceType::GLXDrawable, prodGL, caps, allocator, flags)
{ }
+3 -3
View File
@@ -35,7 +35,7 @@ using namespace mozilla::layers;
using namespace android;
SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
: SurfaceFactory(SharedSurfaceType::Gralloc, prodGL, caps, allocator, flags)
{
@@ -48,7 +48,7 @@ SharedSurface_Gralloc::Create(GLContext* prodGL,
const gfx::IntSize& size,
bool hasAlpha,
layers::TextureFlags flags,
ISurfaceAllocator* allocator)
ClientIPCAllocator* allocator)
{
GLLibraryEGL* egl = &sEGLLibrary;
MOZ_ASSERT(egl);
@@ -118,7 +118,7 @@ SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext* prodGL,
const gfx::IntSize& size,
bool hasAlpha,
GLLibraryEGL* egl,
layers::ISurfaceAllocator* allocator,
layers::ClientIPCAllocator* allocator,
layers::TextureClient* textureClient,
GLuint prodTex)
: SharedSurface(SharedSurfaceType::Gralloc,
+5 -5
View File
@@ -12,7 +12,7 @@
namespace mozilla {
namespace layers {
class ISurfaceAllocator;
class ClientIPCAllocator;
class TextureClient;
}
@@ -29,7 +29,7 @@ public:
const gfx::IntSize& size,
bool hasAlpha,
layers::TextureFlags flags,
layers::ISurfaceAllocator* allocator);
layers::ClientIPCAllocator* allocator);
static SharedSurface_Gralloc* Cast(SharedSurface* surf) {
MOZ_ASSERT(surf->mType == SharedSurfaceType::Gralloc);
@@ -40,7 +40,7 @@ public:
protected:
GLLibraryEGL* const mEGL;
EGLSync mSync;
RefPtr<layers::ISurfaceAllocator> mAllocator;
RefPtr<layers::ClientIPCAllocator> mAllocator;
RefPtr<layers::TextureClient> mTextureClient;
const GLuint mProdTex;
@@ -48,7 +48,7 @@ protected:
const gfx::IntSize& size,
bool hasAlpha,
GLLibraryEGL* egl,
layers::ISurfaceAllocator* allocator,
layers::ClientIPCAllocator* allocator,
layers::TextureClient* textureClient,
GLuint prodTex);
@@ -83,7 +83,7 @@ class SurfaceFactory_Gralloc
{
public:
SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags);
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
+1 -1
View File
@@ -212,7 +212,7 @@ SharedSurface_IOSurface::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surf
/*static*/ UniquePtr<SurfaceFactory_IOSurface>
SurfaceFactory_IOSurface::Create(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags)
{
gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(),
+2 -2
View File
@@ -77,13 +77,13 @@ public:
// Infallible.
static UniquePtr<SurfaceFactory_IOSurface> Create(GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags);
protected:
const gfx::IntSize mMaxDims;
SurfaceFactory_IOSurface(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const RefPtr<layers::ClientIPCAllocator>& allocator,
const layers::TextureFlags& flags,
const gfx::IntSize& maxDims)
: SurfaceFactory(SharedSurfaceType::IOSurface, gl, caps, allocator, flags)
+45 -36
View File
@@ -10,6 +10,7 @@
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/fallible.h"
#include <algorithm>
#ifdef MOZ_WIDGET_GTK
#include "gfxPlatformGtk.h"
@@ -24,16 +25,16 @@ public:
static MemoryTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aMoz2DBackend,TextureFlags aFlags,
TextureAllocationFlags aAllocFlags,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual void Deallocate(ISurfaceAllocator*) override;
virtual void Deallocate(ClientIPCAllocator*) override;
MemoryTextureData(const BufferDescriptor& aDesc,
gfx::BackendType aMoz2DBackend,
@@ -61,16 +62,16 @@ public:
static ShmemTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
TextureAllocationFlags aAllocFlags,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
virtual void Deallocate(ClientIPCAllocator* aAllocator) override;
ShmemTextureData(const BufferDescriptor& aDesc,
gfx::BackendType aMoz2DBackend, mozilla::ipc::Shmem aShmem)
@@ -110,19 +111,20 @@ BufferTextureData*
BufferTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
TextureAllocationFlags aAllocFlags,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
if (!aAllocator || aAllocator->IsSameProcess()) {
return MemoryTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags,
aAllocFlags, aAllocator);
} else {
} else if (aAllocator->AsShmemAllocator()) {
return ShmemTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags,
aAllocFlags, aAllocator);
}
return nullptr;
}
BufferTextureData*
BufferTextureData::CreateInternal(ISurfaceAllocator* aAllocator,
BufferTextureData::CreateInternal(ClientIPCAllocator* aAllocator,
const BufferDescriptor& aDesc,
gfx::BackendType aMoz2DBackend,
int32_t aBufferSize,
@@ -137,18 +139,19 @@ BufferTextureData::CreateInternal(ISurfaceAllocator* aAllocator,
GfxMemoryImageReporter::DidAlloc(buffer);
return new MemoryTextureData(aDesc, aMoz2DBackend, buffer, aBufferSize);
} else {
} else if (aAllocator->AsShmemAllocator()) {
ipc::Shmem shm;
if (!aAllocator->AllocUnsafeShmem(aBufferSize, OptimalShmemType(), &shm)) {
if (!aAllocator->AsShmemAllocator()->AllocUnsafeShmem(aBufferSize, OptimalShmemType(), &shm)) {
return nullptr;
}
return new ShmemTextureData(aDesc, aMoz2DBackend, shm);
}
return nullptr;
}
BufferTextureData*
BufferTextureData::CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
BufferTextureData::CreateForYCbCrWithBufferSize(ClientIPCAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
int32_t aBufferSize,
TextureFlags aTextureFlags)
@@ -167,7 +170,7 @@ BufferTextureData::CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
}
BufferTextureData*
BufferTextureData::CreateForYCbCr(ISurfaceAllocator* aAllocator,
BufferTextureData::CreateForYCbCr(ClientIPCAllocator* aAllocator,
gfx::IntSize aYSize,
gfx::IntSize aCbCrSize,
StereoMode aStereoMode,
@@ -206,12 +209,12 @@ BufferTextureData::GetFormat() const
bool
BufferTextureData::HasInternalBuffer() const
BufferTextureData::HasIntermediateBuffer() const
{
if (mDescriptor.type() == BufferDescriptor::TYCbCrDescriptor) {
return true;
}
return mDescriptor.get_RGBDescriptor().hasInternalBuffer();
return mDescriptor.get_RGBDescriptor().hasIntermediateBuffer();
}
bool
@@ -245,7 +248,7 @@ BufferTextureData::BorrowDrawTarget()
uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
mDrawTarget = gfx::Factory::CreateDrawTargetForData(mMoz2DBackend,
GetBuffer(), rgb.size(),
stride, rgb.format());
stride, rgb.format(), true);
if (mDrawTarget) {
RefPtr<gfx::DrawTarget> dt = mDrawTarget;
@@ -257,7 +260,7 @@ BufferTextureData::BorrowDrawTarget()
if (mMoz2DBackend != gfx::BackendType::CAIRO) {
mDrawTarget = gfx::Factory::CreateDrawTargetForData(gfx::BackendType::CAIRO,
GetBuffer(), rgb.size(),
stride, rgb.format());
stride, rgb.format(), true);
}
if (!mDrawTarget) {
@@ -397,7 +400,7 @@ MemoryTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
return true;
}
static bool InitBuffer(uint8_t* buf, size_t bufSize, TextureAllocationFlags aAllocFlags)
static bool InitBuffer(uint8_t* buf, size_t bufSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aAllocFlags)
{
if (!buf) {
gfxDebug() << "BufferTextureData: Failed to allocate " << bufSize << " bytes";
@@ -406,7 +409,13 @@ static bool InitBuffer(uint8_t* buf, size_t bufSize, TextureAllocationFlags aAll
if ((aAllocFlags & ALLOC_CLEAR_BUFFER) ||
(aAllocFlags & ALLOC_CLEAR_BUFFER_BLACK)) {
memset(buf, 0, bufSize);
if (aFormat == gfx::SurfaceFormat::B8G8R8X8) {
// Even though BGRX was requested, XRGB_UINT32 is what is meant,
// so use 0xFF000000 to put alpha in the right place.
std::fill_n(reinterpret_cast<uint32_t*>(buf), bufSize / sizeof(uint32_t), 0xFF000000);
} else {
memset(buf, 0, bufSize);
}
}
if (aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE) {
@@ -420,7 +429,7 @@ MemoryTextureData*
MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
TextureAllocationFlags aAllocFlags,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
// Should have used CreateForYCbCr.
MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
@@ -436,24 +445,24 @@ MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
}
uint8_t* buf = new (fallible) uint8_t[bufSize];
if (!InitBuffer(buf, bufSize, aAllocFlags)) {
if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags)) {
return nullptr;
}
auto fwd = aAllocator ? aAllocator->AsCompositableForwarder() : nullptr;
bool hasInternalBuffer = fwd ? ComputeHasIntermediateBuffer(aFormat,
bool hasIntermediateBuffer = fwd ? ComputeHasIntermediateBuffer(aFormat,
fwd->GetCompositorBackendType())
: true;
: true;
GfxMemoryImageReporter::DidAlloc(buf);
BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasInternalBuffer);
BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);
return new MemoryTextureData(descriptor, aMoz2DBackend, buf, bufSize);
}
void
MemoryTextureData::Deallocate(ISurfaceAllocator*)
MemoryTextureData::Deallocate(ClientIPCAllocator*)
{
MOZ_ASSERT(mBuffer);
GfxMemoryImageReporter::WillFree(mBuffer);
@@ -462,7 +471,7 @@ MemoryTextureData::Deallocate(ISurfaceAllocator*)
}
TextureData*
MemoryTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
MemoryTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const
{
@@ -487,13 +496,13 @@ ShmemTextureData*
ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
TextureAllocationFlags aAllocFlags,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
MOZ_ASSERT(aAllocator);
// Should have used CreateForYCbCr.
MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
if (!aAllocator) {
if (!aAllocator || !aAllocator->AsShmemAllocator()) {
return nullptr;
}
@@ -508,21 +517,21 @@ ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
}
mozilla::ipc::Shmem shm;
if (!aAllocator->AllocUnsafeShmem(bufSize, OptimalShmemType(), &shm)) {
if (!aAllocator->AsShmemAllocator()->AllocUnsafeShmem(bufSize, OptimalShmemType(), &shm)) {
return nullptr;
}
uint8_t* buf = shm.get<uint8_t>();
if (!InitBuffer(buf, bufSize, aAllocFlags)) {
if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags)) {
return nullptr;
}
auto fwd = aAllocator->AsCompositableForwarder();
bool hasInternalBuffer = fwd ? ComputeHasIntermediateBuffer(aFormat,
bool hasIntermediateBuffer = fwd ? ComputeHasIntermediateBuffer(aFormat,
fwd->GetCompositorBackendType())
: true;
: true;
BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasInternalBuffer);
BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);
return new ShmemTextureData(descriptor, aMoz2DBackend, shm);
@@ -530,7 +539,7 @@ ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
}
TextureData*
ShmemTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
ShmemTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const
{
@@ -539,9 +548,9 @@ ShmemTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
}
void
ShmemTextureData::Deallocate(ISurfaceAllocator* aAllocator)
ShmemTextureData::Deallocate(ClientIPCAllocator* aAllocator)
{
aAllocator->DeallocShmem(mShmem);
aAllocator->AsShmemAllocator()->DeallocShmem(mShmem);
}
} // namespace
+5 -5
View File
@@ -21,9 +21,9 @@ public:
static BufferTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aMoz2DBackend,TextureFlags aFlags,
TextureAllocationFlags aAllocFlags,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
static BufferTextureData* CreateForYCbCr(ISurfaceAllocator* aAllocator,
static BufferTextureData* CreateForYCbCr(ClientIPCAllocator* aAllocator,
gfx::IntSize aYSize,
gfx::IntSize aCbCrSize,
StereoMode aStereoMode,
@@ -32,7 +32,7 @@ public:
// It is generally better to use CreateForYCbCr instead.
// This creates a half-initialized texture since we don't know the sizes and
// offsets in the buffer.
static BufferTextureData* CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
static BufferTextureData* CreateForYCbCrWithBufferSize(ClientIPCAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
int32_t aSize,
TextureFlags aTextureFlags);
@@ -55,7 +55,7 @@ public:
virtual bool SupportsMoz2D() const override;
virtual bool HasInternalBuffer() const override;
virtual bool HasIntermediateBuffer() const override;
// use TextureClient's default implementation
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
@@ -64,7 +64,7 @@ public:
void SetDesciptor(const BufferDescriptor& aDesc);
protected:
static BufferTextureData* CreateInternal(ISurfaceAllocator* aAllocator,
static BufferTextureData* CreateInternal(ClientIPCAllocator* aAllocator,
const BufferDescriptor& aDesc,
gfx::BackendType aMoz2DBackend,
int32_t aBufferSize,
+2 -15
View File
@@ -55,17 +55,6 @@ D3D11ShareHandleImage::GetAsSourceSurface()
RefPtr<ID3D11Device> device;
texture->GetDevice(getter_AddRefs(device));
RefPtr<IDXGIKeyedMutex> keyedMutex;
if (FAILED(texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(getter_AddRefs(keyedMutex))))) {
NS_WARNING("Failed to QueryInterface for IDXGIKeyedMutex, strange.");
return nullptr;
}
if (FAILED(keyedMutex->AcquireSync(0, 0))) {
NS_WARNING("Failed to acquire sync for keyedMutex, plugin failed to release?");
return nullptr;
}
D3D11_TEXTURE2D_DESC desc;
texture->GetDesc(&desc);
@@ -83,19 +72,16 @@ D3D11ShareHandleImage::GetAsSourceSurface()
if (FAILED(hr)) {
NS_WARNING("Failed to create 2D staging texture.");
keyedMutex->ReleaseSync(0);
return nullptr;
}
RefPtr<ID3D11DeviceContext> context;
device->GetImmediateContext(getter_AddRefs(context));
if (!context) {
keyedMutex->ReleaseSync(0);
return nullptr;
}
context->CopyResource(softTexture, texture);
keyedMutex->ReleaseSync(0);
RefPtr<gfx::DataSourceSurface> surface =
gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8);
@@ -152,7 +138,8 @@ D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
CreateOrRecycle(aFormat,
aSize,
BackendSelector::Content,
layers::TextureFlags::DEFAULT);
layers::TextureFlags::DEFAULT,
TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
return textureClient.forget();
}
+6 -45
View File
@@ -15,11 +15,10 @@ namespace mozilla {
namespace layers {
D3D9SurfaceImage::D3D9SurfaceImage(bool aIsFirstFrame)
D3D9SurfaceImage::D3D9SurfaceImage()
: Image(nullptr, ImageFormat::D3D9_RGB32_TEXTURE)
, mSize(0, 0)
, mValid(false)
, mIsFirstFrame(aIsFirstFrame)
, mValid(true)
{}
D3D9SurfaceImage::~D3D9SurfaceImage()
@@ -73,50 +72,16 @@ D3D9SurfaceImage::AllocateAndCopy(D3D9RecycleAllocator* aAllocator,
hr = device->StretchRect(surface, &src, textureSurface, nullptr, D3DTEXF_NONE);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
// Flush the draw command now, so that by the time we come to draw this
// image, we're less likely to need to wait for the draw operation to
// complete.
RefPtr<IDirect3DQuery9> query;
hr = device->CreateQuery(D3DQUERYTYPE_EVENT, getter_AddRefs(query));
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = query->Issue(D3DISSUE_END);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
mTextureClient = textureClient;
mSize = aRegion.Size();
mQuery = query;
return S_OK;
}
bool
D3D9SurfaceImage::IsValid()
already_AddRefed<IDirect3DSurface9>
D3D9SurfaceImage::GetD3D9Surface()
{
EnsureSynchronized();
return mValid;
}
void
D3D9SurfaceImage::EnsureSynchronized()
{
RefPtr<IDirect3DQuery9> query = mQuery;
if (!query) {
// Not setup, or already synchronized.
return;
}
int iterations = 0;
while (iterations < (mIsFirstFrame ? 100 : 10)) {
HRESULT hr = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
if (hr == S_FALSE) {
Sleep(1);
iterations++;
continue;
}
if (hr == S_OK) {
mValid = true;
}
break;
}
mQuery = nullptr;
return static_cast<DXGID3D9TextureData*>(
mTextureClient->GetInternalData())->GetD3D9Surface();
}
const D3DSURFACE_DESC&
@@ -136,7 +101,6 @@ D3D9SurfaceImage::GetTextureClient(CompositableClient* aClient)
{
MOZ_ASSERT(mTextureClient);
MOZ_ASSERT(mTextureClient->GetAllocator() == aClient->GetForwarder());
EnsureSynchronized();
return mTextureClient;
}
@@ -153,9 +117,6 @@ D3D9SurfaceImage::GetAsSourceSurface()
return nullptr;
}
// Ensure that the texture is ready to be used.
EnsureSynchronized();
DXGID3D9TextureData* texData = static_cast<DXGID3D9TextureData*>(mTextureClient->GetInternalData());
// Readback the texture from GPU memory into system memory, so that
// we can copy it into the Cairo image. This is expensive.
+6 -8
View File
@@ -47,7 +47,7 @@ protected:
// resource is ready to use.
class D3D9SurfaceImage : public Image {
public:
explicit D3D9SurfaceImage(bool aIsFirstFrame);
explicit D3D9SurfaceImage();
virtual ~D3D9SurfaceImage();
HRESULT AllocateAndCopy(D3D9RecycleAllocator* aAllocator,
@@ -63,19 +63,17 @@ public:
virtual TextureClient* GetTextureClient(CompositableClient* aClient) override;
virtual bool IsValid() override;
already_AddRefed<IDirect3DSurface9> GetD3D9Surface();
virtual bool IsValid() override { return mValid; }
void Invalidate() { mValid = false; }
private:
// Blocks the calling thread until the copy operation started in SetData()
// is complete, whereupon the texture is safe to use.
void EnsureSynchronized();
gfx::IntSize mSize;
RefPtr<IDirect3DQuery9> mQuery;
RefPtr<TextureClient> mTextureClient;
bool mValid;
bool mIsFirstFrame;
};
} // namepace layers
+1 -1
View File
@@ -73,7 +73,7 @@ GrallocImage::SetData(const Data& aData)
return false;
}
ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
ClientIPCAllocator* allocator = ImageBridgeChild::GetSingleton();
GrallocTextureData* texData = GrallocTextureData::Create(mData.mYSize, HAL_PIXEL_FORMAT_YV12,
gfx::BackendType::NONE,
GraphicBuffer::USAGE_SW_READ_OFTEN |
+2
View File
@@ -250,7 +250,9 @@ Layer::Layer(LayerManager* aManager, void* aImplData) :
mScrollbarDirection(ScrollDirection::NONE),
mScrollbarThumbRatio(0.0f),
mIsScrollbarContainer(false),
#ifdef DEBUG
mDebugColorIndex(0),
#endif
mAnimationGeneration(0)
{
MOZ_COUNT_CTOR(Layer);
+3 -1
View File
@@ -1845,7 +1845,9 @@ protected:
// CSS pixels of the scrollframe's space).
float mScrollbarThumbRatio;
bool mIsScrollbarContainer;
DebugOnly<uint32_t> mDebugColorIndex;
#ifdef DEBUG
uint32_t mDebugColorIndex;
#endif
// If this layer is used for OMTA, then this counter is used to ensure we
// stay in sync with the animation manager
uint64_t mAnimationGeneration;
+11 -11
View File
@@ -24,7 +24,7 @@ public:
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
@@ -33,7 +33,7 @@ public:
static
DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
virtual void Deallocate(ISurfaceAllocator* aAllocator) override
virtual void Deallocate(ClientIPCAllocator* aAllocator) override
{
mSurface = nullptr;
}
@@ -61,7 +61,7 @@ public:
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
@@ -69,7 +69,7 @@ public:
static
DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
void DeallocateData()
{
@@ -84,7 +84,7 @@ public:
}
}
virtual void Deallocate(ISurfaceAllocator* aAllocator) override
virtual void Deallocate(ClientIPCAllocator* aAllocator) override
{
DeallocateData();
}
@@ -125,7 +125,7 @@ DIBTextureData::BorrowDrawTarget()
DIBTextureData*
DIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
if (!aAllocator) {
return nullptr;
@@ -141,7 +141,7 @@ DIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
}
TextureData*
MemoryDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
MemoryDIBTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const
{
@@ -204,7 +204,7 @@ MemoryDIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
}
TextureData*
ShmemDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
ShmemDIBTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const
{
@@ -268,9 +268,9 @@ ShmemDIBTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
DIBTextureData*
ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
MOZ_ASSERT(aAllocator->ParentPid() != base::ProcessId());
MOZ_ASSERT(aAllocator->AsLayerForwarder()->GetParentPid() != base::ProcessId());
DWORD mapSize = aSize.width * aSize.height * BytesPerPixel(aFormat);
HANDLE fileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, mapSize, NULL);
@@ -332,7 +332,7 @@ ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
HANDLE hostHandle = NULL;
if (!ipc::DuplicateHandle(fileMapping, aAllocator->ParentPid(),
if (!ipc::DuplicateHandle(fileMapping, aAllocator->AsLayerForwarder()->GetParentPid(),
&hostHandle, 0, DUPLICATE_SAME_ACCESS)) {
gfxCriticalError() << "Failed to duplicate handle to parent process for surface.";
::DeleteObject(bitmap);
+3 -3
View File
@@ -30,11 +30,11 @@ public:
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
virtual bool HasInternalBuffer() const override { return true; }
virtual bool HasIntermediateBuffer() const override { return true; }
static
DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
protected:
DIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
@@ -80,7 +80,7 @@ public:
virtual void Unlock() override;
virtual bool HasInternalBuffer() const { return true; }
virtual bool HasIntermediateBuffer() const { return true; }
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
+3 -3
View File
@@ -96,13 +96,13 @@ X11TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
}
void
X11TextureData::Deallocate(ISurfaceAllocator*)
X11TextureData::Deallocate(ClientIPCAllocator*)
{
mSurface = nullptr;
}
TextureData*
X11TextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
X11TextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const
{
@@ -111,7 +111,7 @@ X11TextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
X11TextureData*
X11TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureFlags aFlags, ISurfaceAllocator* aAllocator)
TextureFlags aFlags, ClientIPCAllocator* aAllocator)
{
MOZ_ASSERT(aSize.width >= 0 && aSize.height >= 0);
if (aSize.width <= 0 || aSize.height <= 0 ||
+4 -4
View File
@@ -17,7 +17,7 @@ class X11TextureData : public TextureData
{
public:
static X11TextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureFlags aFlags, ISurfaceAllocator* aAllocator);
TextureFlags aFlags, ClientIPCAllocator* aAllocator);
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
@@ -33,12 +33,12 @@ public:
virtual bool SupportsMoz2D() const override { return true; }
virtual bool HasInternalBuffer() const override { return false; }
virtual bool HasIntermediateBuffer() const override { return false; }
virtual void Deallocate(ISurfaceAllocator*) override;
virtual void Deallocate(ClientIPCAllocator*) override;
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
+3 -3
View File
@@ -182,7 +182,7 @@ static inline void SwapRB_R8G8B8A8(uint8_t* pixel) {
class TexClientFactory
{
ISurfaceAllocator* const mAllocator;
ClientIPCAllocator* const mAllocator;
const bool mHasAlpha;
const gfx::IntSize mSize;
const gfx::BackendType mBackendType;
@@ -190,7 +190,7 @@ class TexClientFactory
const LayersBackend mLayersBackend;
public:
TexClientFactory(ISurfaceAllocator* allocator, bool hasAlpha,
TexClientFactory(ClientIPCAllocator* allocator, bool hasAlpha,
const gfx::IntSize& size, gfx::BackendType backendType,
TextureFlags baseTexFlags, LayersBackend layersBackend)
: mAllocator(allocator)
@@ -238,7 +238,7 @@ public:
};
static already_AddRefed<TextureClient>
TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
TexClientFromReadback(SharedSurface* src, ClientIPCAllocator* allocator,
TextureFlags baseFlags, LayersBackend layersBackend)
{
auto backendType = gfx::BackendType::CAIRO;
+1 -1
View File
@@ -538,7 +538,7 @@ ClientLayerManager::MakeSnapshotIfRequired()
DrawOptions(1.0f, CompositionOp::OP_OVER));
dt->SetTransform(oldMatrix);
}
mForwarder->DestroySharedSurface(&inSnapshot);
mForwarder->DestroySurfaceDescriptor(&inSnapshot);
}
}
}
+3 -3
View File
@@ -62,12 +62,12 @@ RemoveTextureFromCompositableTracker::ReleaseTextureClient()
{
if (mTextureClient &&
mTextureClient->GetAllocator() &&
!mTextureClient->GetAllocator()->IsImageBridgeChild())
!mTextureClient->GetAllocator()->UsesImageBridge())
{
TextureClientReleaseTask* task = new TextureClientReleaseTask(mTextureClient);
RefPtr<ISurfaceAllocator> allocator = mTextureClient->GetAllocator();
RefPtr<ClientIPCAllocator> allocator = mTextureClient->GetAllocator();
mTextureClient = nullptr;
allocator->GetMessageLoop()->PostTask(FROM_HERE, task);
allocator->AsClientAllocator()->GetMessageLoop()->PostTask(FROM_HERE, task);
} else {
mTextureClient = nullptr;
}
+1 -2
View File
@@ -75,8 +75,7 @@ void
ImageClient::RemoveTextureWithWaiter(TextureClient* aTexture,
AsyncTransactionWaiter* aAsyncTransactionWaiter)
{
if ((aAsyncTransactionWaiter ||
GetForwarder()->IsImageBridgeChild())
if ((aAsyncTransactionWaiter || GetForwarder()->UsesImageBridge())
#ifndef MOZ_WIDGET_GONK
// If the texture client is taking part in recycling then we should make sure
// the host has finished with it before dropping the ref and triggering
@@ -209,7 +209,7 @@ ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
mTile.Flip();
UnlockTile(mTile);
if (backBuffer->HasInternalBuffer()) {
if (backBuffer->HasIntermediateBuffer()) {
// If our new buffer has an internal buffer, we don't want to keep another
// TextureClient around unnecessarily, so discard the back-buffer.
mTile.DiscardBackBuffer();
+41 -23
View File
@@ -73,9 +73,10 @@ struct TextureDeallocParams
{
TextureData* data;
RefPtr<TextureChild> actor;
RefPtr<ISurfaceAllocator> allocator;
RefPtr<ClientIPCAllocator> allocator;
bool clientDeallocation;
bool syncDeallocation;
bool workAroundSharedSurfaceOwnershipIssue;
};
void DeallocateTextureClient(TextureDeallocParams params);
@@ -132,9 +133,18 @@ public:
SendClientRecycle();
}
void CancelWaitForCompositorRecycle()
{
RECYCLE_LOG("[CLIENT] Cancelling wait for recycle %p\n", mWaitForRecycle.get());
{
MonitorAutoLock mon(mMonitor);
mWaitForRecycle = nullptr;
}
}
CompositableForwarder* GetForwarder() { return mForwarder; }
ISurfaceAllocator* GetAllocator() { return mForwarder; }
ClientIPCAllocator* GetAllocator() { return mForwarder; }
void ActorDestroy(ActorDestroyReason why) override;
@@ -179,7 +189,7 @@ private:
};
static void DestroyTextureData(TextureData* aTextureData, ISurfaceAllocator* aAllocator,
static void DestroyTextureData(TextureData* aTextureData, ClientIPCAllocator* aAllocator,
bool aDeallocate, bool aMainThreadOnly)
{
if (!aTextureData) {
@@ -187,7 +197,7 @@ static void DestroyTextureData(TextureData* aTextureData, ISurfaceAllocator* aAl
}
if (aMainThreadOnly && !NS_IsMainThread()) {
RefPtr<ISurfaceAllocator> allocatorRef = aAllocator;
RefPtr<ClientIPCAllocator> allocatorRef = aAllocator;
NS_DispatchToMainThread(NS_NewRunnableFunction([aTextureData, allocatorRef, aDeallocate]() -> void {
DestroyTextureData(aTextureData, allocatorRef, aDeallocate, true);
}));
@@ -239,7 +249,7 @@ DeallocateTextureClient(TextureDeallocParams params)
MessageLoop* ipdlMsgLoop = nullptr;
if (params.allocator) {
ipdlMsgLoop = params.allocator->GetMessageLoop();
ipdlMsgLoop = params.allocator->AsClientAllocator()->GetMessageLoop();
if (!ipdlMsgLoop) {
// An allocator with no message loop means we are too late in the shutdown
// sequence.
@@ -273,7 +283,7 @@ DeallocateTextureClient(TextureDeallocParams params)
if (!ipdlMsgLoop) {
// If we don't have a message loop we can't know for sure that we are in
// the IPDL thread and use the ISurfaceAllocator.
// the IPDL thread and use the ClientIPCAllocator.
// This should ideally not happen outside of gtest, but some shutdown raciness
// could put us in this situation.
params.allocator = nullptr;
@@ -282,9 +292,14 @@ DeallocateTextureClient(TextureDeallocParams params)
if (!actor) {
// We don't have an IPDL actor, probably because we destroyed the TextureClient
// before sharing it with the compositor. It means the data cannot be owned by
// the TextureHost since we never created the TextureHost.
// the TextureHost since we never created the TextureHost...
// ..except if the lovely mWorkaroundAnnoyingSharedSurfaceOwnershipIssues member
// is set to true. In this case we are in a special situation where this
// TextureClient is in wrapped into another TextureClient which assumes it owns
// our data. This is specific to the gralloc SharedSurface.
bool shouldDeallocate = !params.workAroundSharedSurfaceOwnershipIssue;
DestroyTextureData(params.data, params.allocator,
true, // client-side deallocation
shouldDeallocate,
false); // main-thread deallocation
return;
}
@@ -331,6 +346,7 @@ void TextureClient::Destroy(bool aForceSync)
params.actor = actor;
params.allocator = mAllocator;
params.clientDeallocation = !!(mFlags & TextureFlags::DEALLOCATE_CLIENT);
params.workAroundSharedSurfaceOwnershipIssue = mWorkaroundAnnoyingSharedSurfaceOwnershipIssues;
if (mWorkaroundAnnoyingSharedSurfaceLifetimeIssues) {
params.data = nullptr;
} else {
@@ -397,10 +413,10 @@ TextureClient::Unlock()
}
bool
TextureClient::HasInternalBuffer() const
TextureClient::HasIntermediateBuffer() const
{
MOZ_ASSERT(IsValid());
return mData->HasInternalBuffer();
return mData->HasIntermediateBuffer();
}
gfx::IntSize
@@ -616,6 +632,14 @@ TextureClient::WaitForCompositorRecycle()
}
}
void
TextureClient::CancelWaitForCompositorRecycle()
{
if (IsSharedWithCompositor()) {
mActor->CancelWaitForCompositorRecycle();
}
}
void
TextureClient::SetAddedToCompositableClient()
{
@@ -645,7 +669,7 @@ TextureClient::SetRecycleAllocator(TextureClientRecycleAllocator* aAllocator)
bool
TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
{
MOZ_ASSERT(aForwarder && aForwarder->GetMessageLoop() == mAllocator->GetMessageLoop());
MOZ_ASSERT(aForwarder && aForwarder->GetMessageLoop() == mAllocator->AsClientAllocator()->GetMessageLoop());
if (mActor && !mActor->mDestroyed && mActor->GetForwarder() == aForwarder) {
return true;
}
@@ -779,7 +803,7 @@ TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
// static
already_AddRefed<TextureClient>
TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
TextureClient::CreateForRawBufferAccess(ClientIPCAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2DBackend,
@@ -799,13 +823,6 @@ TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
return nullptr;
}
if (aFormat == SurfaceFormat::B8G8R8X8 &&
(aAllocFlags != TextureAllocationFlags::ALLOC_CLEAR_BUFFER_BLACK) &&
aMoz2DBackend == gfx::BackendType::SKIA) {
// skia requires alpha component of RGBX textures to be 255.
aAllocFlags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE;
}
TextureData* texData = BufferTextureData::Create(aSize, aFormat, aMoz2DBackend,
aTextureFlags, aAllocFlags,
aAllocator);
@@ -818,7 +835,7 @@ TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
// static
already_AddRefed<TextureClient>
TextureClient::CreateForYCbCr(ISurfaceAllocator* aAllocator,
TextureClient::CreateForYCbCr(ClientIPCAllocator* aAllocator,
gfx::IntSize aYSize,
gfx::IntSize aCbCrSize,
StereoMode aStereoMode,
@@ -845,7 +862,7 @@ TextureClient::CreateForYCbCr(ISurfaceAllocator* aAllocator,
// static
already_AddRefed<TextureClient>
TextureClient::CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
TextureClient::CreateForYCbCrWithBufferSize(ClientIPCAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
size_t aSize,
TextureFlags aTextureFlags)
@@ -866,7 +883,7 @@ TextureClient::CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
}
TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator)
TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator)
: mAllocator(aAllocator)
, mActor(nullptr)
, mData(aData)
@@ -878,6 +895,7 @@ TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ISurfaceAl
, mIsLocked(false)
, mAddedToCompositableClient(false)
, mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false)
, mWorkaroundAnnoyingSharedSurfaceOwnershipIssues(false)
#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
, mPoolTracker(nullptr)
#endif
@@ -1027,7 +1045,7 @@ SyncObject::CreateSyncObject(SyncHandle aHandle)
}
already_AddRefed<TextureClient>
TextureClient::CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator)
TextureClient::CreateWithData(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator)
{
if (!aData) {
return nullptr;
+34 -15
View File
@@ -48,7 +48,7 @@ namespace layers {
class AsyncTransactionWaiter;
class CompositableForwarder;
class GrallocTextureData;
class ISurfaceAllocator;
class ClientIPCAllocator;
class CompositableClient;
struct PlanarYCbCrData;
class Image;
@@ -80,6 +80,10 @@ enum TextureAllocationFlags {
// TextureClientD3D11, which may otherwise choose D3D10 or non-KeyedMutex
// surfaces when used on the main thread.
ALLOC_FOR_OUT_OF_BAND_CONTENT = 1 << 5,
// Disable any cross-device synchronization. This is also for TextureClientD3D11,
// and creates a texture without KeyedMutex.
ALLOC_MANUAL_SYNCHRONIZATION = 1 << 6,
};
#ifdef XP_WIN
@@ -193,7 +197,7 @@ public:
virtual bool CanExposeMappedData() const { return false; }
virtual bool HasInternalBuffer() const = 0;
virtual bool HasIntermediateBuffer() const = 0;
virtual bool HasSynchronization() const { return false; }
@@ -203,15 +207,15 @@ public:
virtual bool BorrowMappedYCbCrData(MappedYCbCrTextureData&) { return false; }
virtual void Deallocate(ISurfaceAllocator* aAllocator) = 0;
virtual void Deallocate(ClientIPCAllocator* aAllocator) = 0;
/// Depending on the texture's flags either Deallocate or Forget is called.
virtual void Forget(ISurfaceAllocator* aAllocator) {}
virtual void Forget(ClientIPCAllocator* aAllocator) {}
virtual bool Serialize(SurfaceDescriptor& aDescriptor) = 0;
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const { return nullptr; }
@@ -263,12 +267,12 @@ class TextureClient
: public AtomicRefCountedWithFinalize<TextureClient>
{
public:
explicit TextureClient(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
explicit TextureClient(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator);
virtual ~TextureClient();
static already_AddRefed<TextureClient>
CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
CreateWithData(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator);
// Creates and allocates a TextureClient usable with Moz2D.
static already_AddRefed<TextureClient>
@@ -281,7 +285,7 @@ public:
// Creates and allocates a TextureClient supporting the YCbCr format.
static already_AddRefed<TextureClient>
CreateForYCbCr(ISurfaceAllocator* aAllocator,
CreateForYCbCr(ClientIPCAllocator* aAllocator,
gfx::IntSize aYSize,
gfx::IntSize aCbCrSize,
StereoMode aStereoMode,
@@ -290,7 +294,7 @@ public:
// Creates and allocates a TextureClient (can be accessed through raw
// pointers).
static already_AddRefed<TextureClient>
CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
CreateForRawBufferAccess(ClientIPCAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
gfx::BackendType aMoz2dBackend,
@@ -301,7 +305,7 @@ public:
// pointers) with a certain buffer size. It's unfortunate that we need this.
// providing format and sizes could let us do more optimization.
static already_AddRefed<TextureClient>
CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
CreateForYCbCrWithBufferSize(ClientIPCAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
size_t aSize,
TextureFlags aTextureFlags);
@@ -413,7 +417,7 @@ public:
* in-memory buffer. The consequence of this is that locking the
* TextureClient does not contend with locking the texture on the host side.
*/
bool HasInternalBuffer() const;
bool HasIntermediateBuffer() const;
/**
* Allocate and deallocate a TextureChild actor.
@@ -463,6 +467,12 @@ public:
*/
void WaitForCompositorRecycle();
/**
* Should only be called when dying. We no longer care whether the compositor
* has finished with the texture.
*/
void CancelWaitForCompositorRecycle();
/**
* After being shared with the compositor side, an immutable texture is never
* modified, it can only be read. It is safe to not Lock/Unlock immutable
@@ -571,7 +581,7 @@ public:
void SyncWithObject(SyncObject* aFence) { mData->SyncWithObject(aFence); }
ISurfaceAllocator* GetAllocator() { return mAllocator; }
ClientIPCAllocator* GetAllocator() { return mAllocator; }
TextureClientRecycleAllocator* GetRecycleAllocator() { return mRecycleAllocator; }
void SetRecycleAllocator(TextureClientRecycleAllocator* aAllocator);
@@ -609,7 +619,7 @@ protected:
bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor);
RefPtr<ISurfaceAllocator> mAllocator;
RefPtr<ClientIPCAllocator> mAllocator;
RefPtr<TextureChild> mActor;
RefPtr<TextureClientRecycleAllocator> mRecycleAllocator;
RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
@@ -623,11 +633,14 @@ protected:
gl::GfxTextureWasteTracker mWasteTracker;
OpenMode mOpenMode;
DebugOnly<uint32_t> mExpectedDtRefs;
#ifdef DEBUG
uint32_t mExpectedDtRefs;
#endif
bool mIsLocked;
bool mAddedToCompositableClient;
bool mWorkaroundAnnoyingSharedSurfaceLifetimeIssues;
bool mWorkaroundAnnoyingSharedSurfaceOwnershipIssues;
RefPtr<TextureReadbackSink> mReadbackSink;
@@ -677,7 +690,9 @@ public:
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
mSucceeded = mTexture->Lock(aMode);
#ifdef DEBUG
mChecked = false;
#endif
}
~TextureClientAutoLock() {
MOZ_ASSERT(mChecked);
@@ -687,13 +702,17 @@ public:
}
bool Succeeded() {
#ifdef DEBUG
mChecked = true;
#endif
return mSucceeded;
}
private:
TextureClient* mTexture;
DebugOnly<bool> mChecked;
#ifdef DEBUG
bool mChecked;
#endif
bool mSucceeded;
};
@@ -83,7 +83,8 @@ TextureClientRecycleAllocator::CreateOrRecycle(gfx::SurfaceFormat aFormat,
// This class does not handle ContentClient's TextureClient allocation.
MOZ_ASSERT(aAllocFlags == TextureAllocationFlags::ALLOC_DEFAULT ||
aAllocFlags == TextureAllocationFlags::ALLOC_DISALLOW_BUFFERTEXTURECLIENT ||
aAllocFlags == TextureAllocationFlags::ALLOC_FOR_OUT_OF_BAND_CONTENT);
aAllocFlags == TextureAllocationFlags::ALLOC_FOR_OUT_OF_BAND_CONTENT ||
aAllocFlags == TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
MOZ_ASSERT(!(aTextureFlags & TextureFlags::RECYCLE));
aTextureFlags = aTextureFlags | TextureFlags::RECYCLE; // Set recycle flag
@@ -32,7 +32,7 @@ SharedSurfaceTextureData::~SharedSurfaceTextureData()
{}
void
SharedSurfaceTextureData::Deallocate(ISurfaceAllocator*)
SharedSurfaceTextureData::Deallocate(ClientIPCAllocator*)
{}
gfx::IntSize
@@ -50,7 +50,7 @@ SharedSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
SharedSurfaceTextureClient::SharedSurfaceTextureClient(SharedSurfaceTextureData* aData,
TextureFlags aFlags,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
: TextureClient(aData, aFlags, aAllocator)
{
mWorkaroundAnnoyingSharedSurfaceLifetimeIssues = true;
@@ -58,7 +58,7 @@ SharedSurfaceTextureClient::SharedSurfaceTextureClient(SharedSurfaceTextureData*
already_AddRefed<SharedSurfaceTextureClient>
SharedSurfaceTextureClient::Create(UniquePtr<gl::SharedSurface> surf, gl::SurfaceFactory* factory,
ISurfaceAllocator* aAllocator, TextureFlags aFlags)
ClientIPCAllocator* aAllocator, TextureFlags aFlags)
{
if (!surf) {
return nullptr;
@@ -44,7 +44,7 @@ public:
virtual void Unlock() override {}
virtual bool HasInternalBuffer() const override { return false; }
virtual bool HasIntermediateBuffer() const override { return false; }
virtual gfx::SurfaceFormat GetFormat() const override {
return gfx::SurfaceFormat::UNKNOWN;
@@ -54,7 +54,7 @@ public:
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual void Deallocate(ISurfaceAllocator*) override;
virtual void Deallocate(ClientIPCAllocator*) override;
gl::SharedSurface* Surf() const { return mSurf.get(); }
};
@@ -64,13 +64,13 @@ class SharedSurfaceTextureClient : public TextureClient
public:
SharedSurfaceTextureClient(SharedSurfaceTextureData* aData,
TextureFlags aFlags,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
~SharedSurfaceTextureClient();
static already_AddRefed<SharedSurfaceTextureClient>
Create(UniquePtr<gl::SharedSurface> surf, gl::SurfaceFactory* factory,
ISurfaceAllocator* aAllocator, TextureFlags aFlags);
ClientIPCAllocator* aAllocator, TextureFlags aFlags);
virtual void SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle) override;
+12 -5
View File
@@ -387,7 +387,7 @@ gfxMemorySharedReadLock::GetReadCount()
return mReadCount;
}
gfxShmSharedReadLock::gfxShmSharedReadLock(ISurfaceAllocator* aAllocator)
gfxShmSharedReadLock::gfxShmSharedReadLock(ClientIPCAllocator* aAllocator)
: mAllocator(aAllocator)
, mAllocSuccess(false)
{
@@ -395,7 +395,8 @@ gfxShmSharedReadLock::gfxShmSharedReadLock(ISurfaceAllocator* aAllocator)
MOZ_ASSERT(mAllocator);
if (mAllocator) {
#define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
if (mAllocator->AllocShmemSection(MOZ_ALIGN_WORD(sizeof(ShmReadLockInfo)), &mShmemSection)) {
if (mAllocator->AsLayerForwarder()->GetTileLockAllocator()->AllocShmemSection(
MOZ_ALIGN_WORD(sizeof(ShmReadLockInfo)), &mShmemSection)) {
ShmReadLockInfo* info = GetShmReadLockInfoPtr();
info->readCount = 1;
mAllocSuccess = true;
@@ -427,7 +428,13 @@ gfxShmSharedReadLock::ReadUnlock() {
int32_t readCount = PR_ATOMIC_DECREMENT(&info->readCount);
MOZ_ASSERT(readCount >= 0);
if (readCount <= 0) {
mAllocator->FreeShmemSection(mShmemSection);
auto fwd = mAllocator->AsLayerForwarder();
if (fwd) {
fwd->GetTileLockAllocator()->DeallocShmemSection(mShmemSection);
} else {
// we are on the compositor process
FixedSizeSmallShmemSectionAllocator::FreeShmemSection(mShmemSection);
}
}
return readCount;
}
@@ -725,7 +732,7 @@ TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion,
// Try to re-use the front-buffer if possible
bool createdTextureClient = false;
if (mFrontBuffer &&
mFrontBuffer->HasInternalBuffer() &&
mFrontBuffer->HasIntermediateBuffer() &&
mFrontLock->GetReadCount() == 1 &&
!(aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA && !mFrontBufferOnWhite)) {
// If we had a backbuffer we no longer care about it since we'll
@@ -1362,7 +1369,7 @@ ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
// Note, we don't call UpdatedTexture. The Updated function is called manually
// by the TiledContentHost before composition.
if (backBuffer->HasInternalBuffer()) {
if (backBuffer->HasIntermediateBuffer()) {
// If our new buffer has an internal buffer, we don't want to keep another
// TextureClient around unnecessarily, so discard the back-buffer.
aTile.DiscardBackBuffer();
+1 -1
View File
@@ -97,7 +97,7 @@ private:
};
public:
explicit gfxShmSharedReadLock(ISurfaceAllocator* aAllocator);
explicit gfxShmSharedReadLock(ClientIPCAllocator* aAllocator);
protected:
~gfxShmSharedReadLock();
+1 -1
View File
@@ -108,7 +108,7 @@ ImageHost::SetCurrentTextureHost(TextureHost* aTexture)
}
bool swapTextureSources = !!mCurrentTextureHost && !!mCurrentTextureSource
&& mCurrentTextureHost->HasInternalBuffer();
&& mCurrentTextureHost->HasIntermediateBuffer();
if (swapTextureSources) {
auto dataSource = mCurrentTextureSource->AsDataTextureSource();
+19 -6
View File
@@ -395,14 +395,14 @@ BufferTextureHost::BufferTextureHost(const BufferDescriptor& aDesc,
const YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
mSize = ycbcr.ySize();
mFormat = gfx::SurfaceFormat::YUV;
mHasInternalBuffer = true;
mHasIntermediateBuffer = true;
break;
}
case BufferDescriptor::TRGBDescriptor: {
const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
mSize = rgb.size();
mFormat = rgb.format();
mHasInternalBuffer = rgb.hasInternalBuffer();
mHasIntermediateBuffer = rgb.hasIntermediateBuffer();
break;
}
default: MOZ_CRASH();
@@ -496,7 +496,7 @@ BufferTextureHost::Unlock()
bool
BufferTextureHost::EnsureWrappingTextureSource()
{
MOZ_ASSERT(!mHasInternalBuffer);
MOZ_ASSERT(!mHasIntermediateBuffer);
MOZ_ASSERT(mFormat != gfx::SurfaceFormat::YUV);
if (mFirstSource) {
@@ -516,6 +516,16 @@ BufferTextureHost::EnsureWrappingTextureSource()
}
mFirstSource = mCompositor->CreateDataTextureSourceAround(surf);
if (!mFirstSource) {
// BasicCompositor::CreateDataTextureSourceAround never returns null
// and we don't expect to take this branch if we are using another backend.
// Returning false is fine but if we get into this situation it probably
// means something fishy is going on, like a texture being used with
// several compositor backends.
NS_WARNING("Failed to use a BufferTextureHost without intermediate buffer");
return false;
}
mFirstSource->SetUpdateSerial(mUpdateSerial);
mFirstSource->SetOwner(this);
@@ -525,7 +535,7 @@ BufferTextureHost::EnsureWrappingTextureSource()
void
BufferTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
{
if (!mHasInternalBuffer) {
if (!mHasIntermediateBuffer) {
EnsureWrappingTextureSource();
}
@@ -543,9 +553,11 @@ BufferTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
bool compatibleFormats = texture
&& (mFormat == texture->GetFormat()
|| (mFormat == gfx::SurfaceFormat::YUV
&& mCompositor
&& mCompositor->SupportsEffect(EffectTypes::YCBCR)
&& texture->GetNextSibling())
|| (mFormat == gfx::SurfaceFormat::YUV
&& mCompositor
&& !mCompositor->SupportsEffect(EffectTypes::YCBCR)
&& texture->GetFormat() == gfx::SurfaceFormat::B8G8R8X8));
@@ -557,6 +569,7 @@ BufferTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
if (!shouldCreateTexture) {
mFirstSource = texture;
mFirstSource->SetOwner(this);
mNeedsFullUpdate = true;
}
}
@@ -629,7 +642,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
// attached to a layer.
return false;
}
if (!mHasInternalBuffer && EnsureWrappingTextureSource()) {
if (!mHasIntermediateBuffer && EnsureWrappingTextureSource()) {
return true;
}
@@ -788,7 +801,7 @@ ShmemTextureHost::DeallocateSharedData()
if (mShmem) {
MOZ_ASSERT(mDeallocator,
"Shared memory would leak without a ISurfaceAllocator");
mDeallocator->DeallocShmem(*mShmem);
mDeallocator->AsShmemAllocator()->DeallocShmem(*mShmem);
mShmem = nullptr;
}
}
+3 -3
View File
@@ -530,7 +530,7 @@ public:
* in-memory buffer. The consequence of this is that locking the
* TextureHost does not contend with locking the texture on the client side.
*/
virtual bool HasInternalBuffer() const { return false; }
virtual bool HasIntermediateBuffer() const { return false; }
void AddCompositableRef() { ++mCompositableCount; }
@@ -630,7 +630,7 @@ public:
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
virtual bool HasInternalBuffer() const override { return mHasInternalBuffer; }
virtual bool HasIntermediateBuffer() const override { return mHasIntermediateBuffer; }
protected:
bool Upload(nsIntRegion *aRegion = nullptr);
@@ -648,7 +648,7 @@ protected:
uint32_t mUpdateSerial;
bool mLocked;
bool mNeedsFullUpdate;
bool mHasInternalBuffer;
bool mHasIntermediateBuffer;
};
/**
+2 -2
View File
@@ -150,7 +150,7 @@ UseTileTexture(CompositableTextureHostRef& aTexture,
// We possibly upload the entire texture contents here. This is a purposeful
// decision, as sub-image upload can often be slow and/or unreliable, but
// we may want to reevaluate this in the future.
// For !HasInternalBuffer() textures, this is likely a no-op.
// For !HasIntermediateBuffer() textures, this is likely a no-op.
nsIntRegion region = aUpdateRect;
aTexture->Updated(&region);
#endif
@@ -368,7 +368,7 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
aCompositor);
}
if (tile.mTextureHost->HasInternalBuffer()) {
if (tile.mTextureHost->HasIntermediateBuffer()) {
// Now that we did the texture upload (in UseTileTexture), we can release
// the lock.
tile.ReadUnlock();
+9 -7
View File
@@ -362,7 +362,9 @@ D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocation
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
if (!NS_IsMainThread() || !!(aFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT)) {
// On the main thread we use the syncobject to handle synchronization.
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
if (!(aFlags & ALLOC_MANUAL_SYNCHRONIZATION)) {
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
}
}
HRESULT hr = d3d11device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(texture11));
@@ -380,7 +382,7 @@ D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocation
}
void
D3D11TextureData::Deallocate(ISurfaceAllocator* aAllocator)
D3D11TextureData::Deallocate(ClientIPCAllocator* aAllocator)
{
mTexture = nullptr;
}
@@ -389,7 +391,7 @@ already_AddRefed<TextureClient>
CreateD3D11TextureClientWithDevice(IntSize aSize, SurfaceFormat aFormat,
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
ID3D11Device* aDevice,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
TextureData* data = D3D11TextureData::Create(aSize, aFormat, aAllocFlags, aDevice);
if (!data) {
@@ -399,7 +401,7 @@ CreateD3D11TextureClientWithDevice(IntSize aSize, SurfaceFormat aFormat,
}
TextureData*
D3D11TextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
D3D11TextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const
{
@@ -413,7 +415,7 @@ D3D11TextureData::GetDXGIResource(IDXGIResource** aOutResource)
}
DXGIYCbCrTextureData*
DXGIYCbCrTextureData::Create(ISurfaceAllocator* aAllocator,
DXGIYCbCrTextureData::Create(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
IUnknown* aTextureY,
IUnknown* aTextureCb,
@@ -445,7 +447,7 @@ DXGIYCbCrTextureData::Create(ISurfaceAllocator* aAllocator,
}
DXGIYCbCrTextureData*
DXGIYCbCrTextureData::Create(ISurfaceAllocator* aAllocator,
DXGIYCbCrTextureData::Create(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
ID3D11Texture2D* aTextureY,
ID3D11Texture2D* aTextureCb,
@@ -507,7 +509,7 @@ DXGIYCbCrTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
}
void
DXGIYCbCrTextureData::Deallocate(ISurfaceAllocator*)
DXGIYCbCrTextureData::Deallocate(ClientIPCAllocator*)
{
mHoldRefs[0] = nullptr;
mHoldRefs[1] = nullptr;
+10 -10
View File
@@ -30,7 +30,7 @@ public:
virtual bool SupportsMoz2D() const override { return true; }
virtual bool HasInternalBuffer() const override { return false; }
virtual bool HasIntermediateBuffer() const override { return false; }
virtual bool HasSynchronization() const override { return mHasSynchronization; }
@@ -76,7 +76,7 @@ public:
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const override;
@@ -85,7 +85,7 @@ public:
ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
virtual void Deallocate(ClientIPCAllocator* aAllocator) override;
D3D11TextureData* AsD3D11TextureData() override {
return this;
@@ -107,13 +107,13 @@ already_AddRefed<TextureClient>
CreateD3D11extureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
ID3D11Device* aDevice,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
class DXGIYCbCrTextureData : public TextureData
{
public:
static DXGIYCbCrTextureData*
Create(ISurfaceAllocator* aAllocator,
Create(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
IUnknown* aTextureY,
IUnknown* aTextureCb,
@@ -126,7 +126,7 @@ public:
const gfx::IntSize& aSizeCbCr);
static DXGIYCbCrTextureData*
Create(ISurfaceAllocator* aAllocator,
Create(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
ID3D11Texture2D* aTextureCb,
ID3D11Texture2D* aTextureY,
@@ -142,7 +142,7 @@ public:
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
// TODO - DXGIYCbCrTextureClient returned true but that looks like a mistake
virtual bool HasInternalBuffer() const override{ return false; }
virtual bool HasIntermediateBuffer() const override{ return false; }
virtual gfx::IntSize GetSize() const override { return mSize; }
@@ -156,9 +156,9 @@ public:
// (ex. component alpha) because the underlying texture is always created by
// an external producer.
virtual DXGIYCbCrTextureData*
CreateSimilar(ISurfaceAllocator*, TextureFlags, TextureAllocationFlags) const override { return nullptr; }
CreateSimilar(ClientIPCAllocator*, TextureFlags, TextureAllocationFlags) const override { return nullptr; }
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
virtual void Deallocate(ClientIPCAllocator* aAllocator) override;
virtual bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
@@ -278,7 +278,7 @@ already_AddRefed<TextureClient>
CreateD3D11TextureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
ID3D11Device* aDevice,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
/**
+1 -1
View File
@@ -576,7 +576,7 @@ D3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
}
TextureData*
D3D9TextureData::CreateSimilar(ISurfaceAllocator*, TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
D3D9TextureData::CreateSimilar(ClientIPCAllocator*, TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
{
return D3D9TextureData::Create(mSize, mFormat, aAllocFlags);
}
+6 -6
View File
@@ -184,7 +184,7 @@ public:
virtual bool SupportsMoz2D() const override { return true; }
virtual bool HasInternalBuffer() const override { return true; }
virtual bool HasIntermediateBuffer() const override { return true; }
virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
@@ -201,14 +201,14 @@ public:
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const override;
static D3D9TextureData*
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
virtual void Deallocate(ISurfaceAllocator* aAllocator) override {}
virtual void Deallocate(ClientIPCAllocator* aAllocator) override {}
protected:
D3D9TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
@@ -246,9 +246,9 @@ public:
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual bool HasInternalBuffer() const override { return false; }
virtual bool HasIntermediateBuffer() const override { return false; }
virtual void Deallocate(ISurfaceAllocator* aAllocator) override {}
virtual void Deallocate(ClientIPCAllocator* aAllocator) override {}
IDirect3DDevice9* GetD3D9Device() { return mDevice; }
IDirect3DTexture9* GetD3D9Texture() { return mTexture; }
@@ -297,7 +297,7 @@ public:
return nullptr;
}
virtual bool HasInternalBuffer() const override { return true; }
virtual bool HasIntermediateBuffer() const override { return true; }
protected:
TextureHostD3D9(TextureFlags aFlags);
@@ -42,7 +42,9 @@ Mutex* AsyncTransactionTracker::sLock = nullptr;
AsyncTransactionTracker::AsyncTransactionTracker(AsyncTransactionWaiter* aWaiter)
: mSerial(GetNextSerial())
, mWaiter(aWaiter)
#ifdef DEBUG
, mCompleted(false)
#endif
{
if (mWaiter) {
mWaiter->IncrementWaitCount();
@@ -57,7 +59,9 @@ void
AsyncTransactionTracker::NotifyComplete()
{
MOZ_ASSERT(!mCompleted);
#ifdef DEBUG
mCompleted = true;
#endif
Complete();
if (mWaiter) {
mWaiter->DecrementWaitCount();
@@ -68,7 +72,9 @@ void
AsyncTransactionTracker::NotifyCancel()
{
MOZ_ASSERT(!mCompleted);
#ifdef DEBUG
mCompleted = true;
#endif
Cancel();
if (mWaiter) {
mWaiter->DecrementWaitCount();
+3 -1
View File
@@ -131,7 +131,9 @@ protected:
uint64_t mSerial;
RefPtr<AsyncTransactionWaiter> mWaiter;
DebugOnly<bool> mCompleted;
#ifdef DEBUG
bool mCompleted;
#endif
/**
* gecko does not provide atomic operation for uint64_t.
+1 -3
View File
@@ -40,7 +40,7 @@ class PTextureChild;
* additionally forward modifications of the Layer tree).
* ImageBridgeChild is another CompositableForwarder.
*/
class CompositableForwarder : public ISurfaceAllocator
class CompositableForwarder : public ClientIPCAllocator
{
public:
@@ -144,8 +144,6 @@ public:
return mTextureFactoryIdentifier.mMaxTextureSize;
}
bool IsOnCompositorSide() const override { return false; }
/**
* Returns the type of backend that is used off the main thread.
* We only don't allow changing the backend type at runtime so this value can
@@ -144,7 +144,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
MOZ_ASSERT(tex.get());
compositable->RemoveTextureHost(tex);
if (!IsAsync() && ImageBridgeParent::GetInstance(GetChildProcessId())) {
if (!UsesImageBridge() && ImageBridgeParent::GetInstance(GetChildProcessId())) {
// send FenceHandle if present via ImageBridge.
ImageBridgeParent::AppendDeliverFenceMessage(
GetChildProcessId(),
@@ -195,7 +195,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
}
compositable->UseTextureHost(textures);
if (IsAsync() && compositable->GetLayer()) {
if (UsesImageBridge() && compositable->GetLayer()) {
ScheduleComposition(op);
}
break;
@@ -209,7 +209,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
MOZ_ASSERT(texOnBlack && texOnWhite);
compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);
if (IsAsync()) {
if (UsesImageBridge()) {
ScheduleComposition(op);
}
break;
@@ -49,14 +49,6 @@ protected:
bool ReceiveCompositableUpdate(const CompositableOperation& aEdit,
EditReplyVector& replyv);
bool IsOnCompositorSide() const override { return true; }
/**
* Return true if this protocol is asynchronous with respect to the content
* thread (ImageBridge for instance).
*/
virtual bool IsAsync() const { return false; }
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {}
std::vector<AsyncParentMessageData> mPendingAsyncMessage;
+1 -370
View File
@@ -6,27 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ISurfaceAllocator.h"
#include <sys/types.h> // for int32_t
#include "gfx2DGlue.h" // for IntSize
#include "gfxPlatform.h" // for gfxPlatform, gfxImageFormat
#include "gfxSharedImageSurface.h" // for gfxSharedImageSurface
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Atomics.h" // for PrimitiveIntrinsics
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "ShadowLayerUtils.h"
#include "mozilla/mozalloc.h" // for operator delete[], etc
#include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
#include "mozilla/ipc/Shmem.h"
#include "mozilla/layers/ImageDataSerializer.h"
#ifdef DEBUG
#include "prenv.h"
#endif
using namespace mozilla::ipc;
namespace mozilla {
namespace layers {
@@ -37,355 +16,7 @@ mozilla::Atomic<ptrdiff_t> GfxMemoryImageReporter::sAmount(0);
mozilla::ipc::SharedMemory::SharedMemoryType OptimalShmemType()
{
return mozilla::ipc::SharedMemory::TYPE_BASIC;
}
bool
IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface)
{
return aSurface.type() != SurfaceDescriptor::T__None &&
aSurface.type() != SurfaceDescriptor::Tnull_t;
}
ISurfaceAllocator::~ISurfaceAllocator()
{
// Check if we're not leaking..
MOZ_ASSERT(mUsedShmems.empty());
}
void
ISurfaceAllocator::Finalize()
{
ShrinkShmemSectionHeap();
}
static inline uint8_t*
GetAddressFromDescriptor(const SurfaceDescriptor& aDescriptor)
{
MOZ_ASSERT(IsSurfaceDescriptorValid(aDescriptor));
MOZ_RELEASE_ASSERT(aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer);
auto memOrShmem = aDescriptor.get_SurfaceDescriptorBuffer().data();
if (memOrShmem.type() == MemoryOrShmem::TShmem) {
return memOrShmem.get_Shmem().get<uint8_t>();
} else {
return reinterpret_cast<uint8_t*>(memOrShmem.get_uintptr_t());
}
}
already_AddRefed<gfx::DrawTarget>
GetDrawTargetForDescriptor(const SurfaceDescriptor& aDescriptor, gfx::BackendType aBackend)
{
uint8_t* data = GetAddressFromDescriptor(aDescriptor);
auto rgb = aDescriptor.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
return gfx::Factory::CreateDrawTargetForData(gfx::BackendType::CAIRO,
data, rgb.size(),
stride, rgb.format());
}
already_AddRefed<gfx::DataSourceSurface>
GetSurfaceForDescriptor(const SurfaceDescriptor& aDescriptor)
{
uint8_t* data = GetAddressFromDescriptor(aDescriptor);
auto rgb = aDescriptor.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
return gfx::Factory::CreateWrappingDataSourceSurface(data, stride, rgb.size(),
rgb.format());
}
bool
ISurfaceAllocator::AllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
SurfaceDescriptor* aBuffer)
{
if (!IPCOpen()) {
return false;
}
return AllocSurfaceDescriptorWithCaps(aSize, aContent, DEFAULT_BUFFER_CAPS, aBuffer);
}
bool
ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer)
{
if (!IPCOpen()) {
return false;
}
gfx::SurfaceFormat format =
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aContent);
size_t size = ImageDataSerializer::ComputeRGBBufferSize(aSize, format);
if (!size) {
return false;
}
MemoryOrShmem bufferDesc;
if (IsSameProcess()) {
uint8_t* data = new (std::nothrow) uint8_t[size];
if (!data) {
return false;
}
GfxMemoryImageReporter::DidAlloc(data);
#ifdef XP_MACOSX
// Workaround a bug in Quartz where drawing an a8 surface to another a8
// surface with OP_SOURCE still requires the destination to be clear.
if (format == gfx::SurfaceFormat::A8) {
memset(data, 0, size);
}
#endif
bufferDesc = reinterpret_cast<uintptr_t>(data);
} else {
mozilla::ipc::SharedMemory::SharedMemoryType shmemType = OptimalShmemType();
mozilla::ipc::Shmem shmem;
if (!AllocUnsafeShmem(size, shmemType, &shmem)) {
return false;
}
bufferDesc = shmem;
}
// Use an intermediate buffer by default. Skipping the intermediate buffer is
// only possible in certain configurations so let's keep it simple here for now.
const bool hasIntermediateBuffer = true;
*aBuffer = SurfaceDescriptorBuffer(RGBDescriptor(aSize, format, hasIntermediateBuffer),
bufferDesc);
return true;
}
/* static */ bool
ISurfaceAllocator::IsShmem(SurfaceDescriptor* aSurface)
{
return aSurface && (aSurface->type() == SurfaceDescriptor::TSurfaceDescriptorBuffer)
&& (aSurface->get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::TShmem);
}
void
ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface)
{
MOZ_ASSERT(IPCOpen());
if (!IPCOpen()) {
return;
}
MOZ_ASSERT(aSurface);
if (!aSurface) {
return;
}
if (!IPCOpen()) {
return;
}
SurfaceDescriptorBuffer& desc = aSurface->get_SurfaceDescriptorBuffer();
switch (desc.data().type()) {
case MemoryOrShmem::TShmem: {
DeallocShmem(desc.data().get_Shmem());
break;
}
case MemoryOrShmem::Tuintptr_t: {
uint8_t* ptr = (uint8_t*)desc.data().get_uintptr_t();
GfxMemoryImageReporter::WillFree(ptr);
delete [] ptr;
break;
}
default:
NS_RUNTIMEABORT("surface type not implemented!");
}
*aSurface = SurfaceDescriptor();
}
// XXX - We should actually figure out the minimum shmem allocation size on
// a certain platform and use that.
const uint32_t sShmemPageSize = 4096;
#ifdef DEBUG
const uint32_t sSupportedBlockSize = 4;
#endif
enum AllocationStatus
{
STATUS_ALLOCATED,
STATUS_FREED
};
struct ShmemSectionHeapHeader
{
Atomic<uint32_t> mTotalBlocks;
Atomic<uint32_t> mAllocatedBlocks;
};
struct ShmemSectionHeapAllocation
{
Atomic<uint32_t> mStatus;
uint32_t mSize;
};
bool
ISurfaceAllocator::AllocShmemSection(size_t aSize, mozilla::layers::ShmemSection* aShmemSection)
{
MOZ_ASSERT(IPCOpen());
if (!IPCOpen()) {
return false;
}
// For now we only support sizes of 4. If we want to support different sizes
// some more complicated bookkeeping should be added.
MOZ_ASSERT(aSize == sSupportedBlockSize);
MOZ_ASSERT(aShmemSection);
uint32_t allocationSize = (aSize + sizeof(ShmemSectionHeapAllocation));
for (size_t i = 0; i < mUsedShmems.size(); i++) {
ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
if ((header->mAllocatedBlocks + 1) * allocationSize + sizeof(ShmemSectionHeapHeader) < sShmemPageSize) {
aShmemSection->shmem() = mUsedShmems[i];
MOZ_ASSERT(mUsedShmems[i].IsWritable());
break;
}
}
if (!aShmemSection->shmem().IsWritable()) {
ipc::Shmem tmp;
if (!AllocUnsafeShmem(sShmemPageSize, ipc::SharedMemory::TYPE_BASIC, &tmp)) {
return false;
}
ShmemSectionHeapHeader* header = tmp.get<ShmemSectionHeapHeader>();
header->mTotalBlocks = 0;
header->mAllocatedBlocks = 0;
mUsedShmems.push_back(tmp);
aShmemSection->shmem() = tmp;
}
MOZ_ASSERT(aShmemSection->shmem().IsWritable());
ShmemSectionHeapHeader* header = aShmemSection->shmem().get<ShmemSectionHeapHeader>();
uint8_t* heap = aShmemSection->shmem().get<uint8_t>() + sizeof(ShmemSectionHeapHeader);
ShmemSectionHeapAllocation* allocHeader = nullptr;
if (header->mTotalBlocks > header->mAllocatedBlocks) {
// Search for the first available block.
for (size_t i = 0; i < header->mTotalBlocks; i++) {
allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
if (allocHeader->mStatus == STATUS_FREED) {
break;
}
heap += allocationSize;
}
MOZ_ASSERT(allocHeader && allocHeader->mStatus == STATUS_FREED);
MOZ_ASSERT(allocHeader->mSize == sSupportedBlockSize);
} else {
heap += header->mTotalBlocks * allocationSize;
header->mTotalBlocks++;
allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
allocHeader->mSize = aSize;
}
MOZ_ASSERT(allocHeader);
header->mAllocatedBlocks++;
allocHeader->mStatus = STATUS_ALLOCATED;
aShmemSection->size() = aSize;
aShmemSection->offset() = (heap + sizeof(ShmemSectionHeapAllocation)) - aShmemSection->shmem().get<uint8_t>();
ShrinkShmemSectionHeap();
return true;
}
void
ISurfaceAllocator::FreeShmemSection(mozilla::layers::ShmemSection& aShmemSection)
{
MOZ_ASSERT(IPCOpen());
if (!IPCOpen()) {
return;
}
MOZ_ASSERT(aShmemSection.size() == sSupportedBlockSize);
MOZ_ASSERT(aShmemSection.offset() < sShmemPageSize - sSupportedBlockSize);
ShmemSectionHeapAllocation* allocHeader =
reinterpret_cast<ShmemSectionHeapAllocation*>(aShmemSection.shmem().get<char>() +
aShmemSection.offset() -
sizeof(ShmemSectionHeapAllocation));
MOZ_ASSERT(allocHeader->mSize == aShmemSection.size());
DebugOnly<bool> success = allocHeader->mStatus.compareExchange(STATUS_ALLOCATED, STATUS_FREED);
// If this fails something really weird is going on.
MOZ_ASSERT(success);
ShmemSectionHeapHeader* header = aShmemSection.shmem().get<ShmemSectionHeapHeader>();
header->mAllocatedBlocks--;
ShrinkShmemSectionHeap();
}
void
ISurfaceAllocator::ShrinkShmemSectionHeap()
{
if (!IPCOpen()) {
return;
}
// The loop will terminate as we either increase i, or decrease size
// every time through.
size_t i = 0;
while (i < mUsedShmems.size()) {
ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
if (header->mAllocatedBlocks == 0) {
DeallocShmem(mUsedShmems[i]);
// We don't particularly care about order, move the last one in the array
// to this position.
if (i < mUsedShmems.size() - 1) {
mUsedShmems[i] = mUsedShmems[mUsedShmems.size() - 1];
}
mUsedShmems.pop_back();
} else {
i++;
}
}
}
bool
ISurfaceAllocator::AllocGrallocBuffer(const gfx::IntSize& aSize,
uint32_t aFormat,
uint32_t aUsage,
MaybeMagicGrallocBufferHandle* aHandle)
{
MOZ_ASSERT(IPCOpen());
if (!IPCOpen()) {
return false;
}
return SharedBufferManagerChild::GetSingleton()->AllocGrallocBuffer(aSize, aFormat, aUsage, aHandle);
}
void
ISurfaceAllocator::DeallocGrallocBuffer(MaybeMagicGrallocBufferHandle* aHandle)
{
MOZ_ASSERT(IPCOpen());
if (!IPCOpen()) {
return;
}
SharedBufferManagerChild::GetSingleton()->DeallocGrallocBuffer(*aHandle);
}
void
ISurfaceAllocator::DropGrallocBuffer(MaybeMagicGrallocBufferHandle* aHandle)
{
MOZ_ASSERT(IPCOpen());
if (!IPCOpen()) {
return;
}
SharedBufferManagerChild::GetSingleton()->DropGrallocBuffer(*aHandle);
return ipc::SharedMemory::SharedMemoryType::TYPE_BASIC;
}
} // namespace layers
+97 -96
View File
@@ -16,11 +16,12 @@
#include "mozilla/Atomics.h" // for Atomic
#include "mozilla/layers/LayersMessages.h" // for ShmemSection
#include "LayersTypes.h"
#include <vector>
#include "gfxPrefs.h"
#include "mozilla/layers/AtomicRefCountedWithFinalize.h"
/*
* FIXME [bjacob] *** PURE CRAZYNESS WARNING ***
* (I think that this doesn't apply anymore.)
*
* This #define is actually needed here, because subclasses of ISurfaceAllocator,
* namely ShadowLayerForwarder, will or will not override AllocGrallocBuffer
@@ -40,8 +41,13 @@ class DataSourceSurface;
namespace layers {
class MaybeMagicGrallocBufferHandle;
class CompositableForwarder;
class ShadowLayerForwarder;
class ShmemAllocator;
class ShmemSectionAllocator;
class LegacySurfaceDescriptorAllocator;
class ClientIPCAllocator;
enum BufferCapabilities {
DEFAULT_BUFFER_CAPS = 0,
@@ -59,12 +65,7 @@ class SurfaceDescriptor;
mozilla::ipc::SharedMemory::SharedMemoryType OptimalShmemType();
bool IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface);
bool IsSurfaceDescriptorOwned(const SurfaceDescriptor& aDescriptor);
bool ReleaseOwnedSurfaceDescriptor(const SurfaceDescriptor& aDescriptor);
already_AddRefed<gfx::DrawTarget> GetDrawTargetForDescriptor(const SurfaceDescriptor& aDescriptor, gfx::BackendType aBackend);
already_AddRefed<gfx::DataSourceSurface> GetSurfaceForDescriptor(const SurfaceDescriptor& aDescriptor);
/**
* An interface used to create and destroy surfaces that are shared with the
* Compositor process (using shmem, or gralloc, or other platform specific memory)
@@ -78,106 +79,106 @@ class ISurfaceAllocator : public AtomicRefCountedWithFinalize<ISurfaceAllocator>
{
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(ISurfaceAllocator)
ISurfaceAllocator()
: mDefaultMessageLoop(MessageLoop::current())
{}
void Finalize();
// down-casting
/**
* Allocate shared memory that can be accessed by only one process at a time.
* Ownership of this memory is passed when the memory is sent in an IPDL
* message.
*/
virtual bool AllocShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aType,
mozilla::ipc::Shmem* aShmem) = 0;
virtual ShmemAllocator* AsShmemAllocator() { return nullptr; }
/**
* Allocate shared memory that can be accessed by both processes at the
* same time. Safety is left for the user of the memory to care about.
*/
virtual bool AllocUnsafeShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aType,
mozilla::ipc::Shmem* aShmem) = 0;
/**
* Allocate memory in shared memory that can always be accessed by both
* processes at a time. Safety is left for the user of the memory to care
* about.
*/
bool AllocShmemSection(size_t aSize,
mozilla::layers::ShmemSection* aShmemSection);
/**
* Deallocates a shmem section.
*/
void FreeShmemSection(mozilla::layers::ShmemSection& aShmemSection);
/**
* Deallocate memory allocated by either AllocShmem or AllocUnsafeShmem.
*/
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) = 0;
// was AllocBuffer
virtual bool AllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
SurfaceDescriptor* aBuffer);
// was AllocBufferWithCaps
virtual bool AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer);
/**
* Returns the maximum texture size supported by the compositor.
*/
virtual int32_t GetMaxTextureSize() const { return INT32_MAX; }
virtual void DestroySharedSurface(SurfaceDescriptor* aSurface);
// method that does the actual allocation work
bool AllocGrallocBuffer(const gfx::IntSize& aSize,
uint32_t aFormat,
uint32_t aUsage,
MaybeMagicGrallocBufferHandle* aHandle);
void DeallocGrallocBuffer(MaybeMagicGrallocBufferHandle* aHandle);
void DropGrallocBuffer(MaybeMagicGrallocBufferHandle* aHandle);
virtual bool IPCOpen() const { return true; }
virtual bool IsSameProcess() const = 0;
virtual base::ProcessId ParentPid() const { return base::ProcessId(); }
virtual bool IsImageBridgeChild() const { return false; }
virtual MessageLoop * GetMessageLoop() const
{
return mDefaultMessageLoop;
}
// Returns true if aSurface wraps a Shmem.
static bool IsShmem(SurfaceDescriptor* aSurface);
virtual ShmemSectionAllocator* AsShmemSectionAllocator() { return nullptr; }
virtual CompositableForwarder* AsCompositableForwarder() { return nullptr; }
virtual ShadowLayerForwarder* AsLayerForwarder() { return nullptr; }
virtual ClientIPCAllocator* AsClientAllocator() { return nullptr; }
virtual LegacySurfaceDescriptorAllocator*
AsLegacySurfaceDescriptorAllocator() { return nullptr; }
// ipc info
virtual bool IPCOpen() const { return true; }
virtual bool IsSameProcess() const = 0;
virtual bool UsesImageBridge() const { return false; }
protected:
void Finalize() {}
virtual bool IsOnCompositorSide() const = 0;
virtual ~ISurfaceAllocator();
void ShrinkShmemSectionHeap();
// This is used to implement an extremely simple & naive heap allocator.
std::vector<mozilla::ipc::Shmem> mUsedShmems;
MessageLoop* mDefaultMessageLoop;
virtual ~ISurfaceAllocator() {}
friend class AtomicRefCountedWithFinalize<ISurfaceAllocator>;
};
/// Methods that are specific to the client/child side.
class ClientIPCAllocator : public ISurfaceAllocator
{
public:
virtual ClientIPCAllocator* AsClientAllocator() override { return this; }
virtual MessageLoop * GetMessageLoop() const = 0;
virtual int32_t GetMaxTextureSize() const { return gfxPrefs::MaxTextureSize(); }
};
/// An allocator can provide shared memory.
///
/// The allocated shmems can be deallocated on either process, as long as they
/// belong to the same channel.
class ShmemAllocator
{
public:
virtual bool AllocShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) = 0;
virtual bool AllocUnsafeShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) = 0;
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) = 0;
};
/// An allocator that can group allocations in bigger chunks of shared memory.
///
/// The allocated shmem sections can only be deallocated by the same allocator
/// instance (and only in the child process).
class ShmemSectionAllocator
{
public:
virtual bool AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection) = 0;
virtual void DeallocShmemSection(ShmemSection& aShmemSection) = 0;
virtual void MemoryPressure() {}
};
/// Some old stuff that's still around and used for screenshots.
///
/// New code should not need this (see TextureClient).
class LegacySurfaceDescriptorAllocator
{
public:
virtual bool AllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
SurfaceDescriptor* aBuffer) = 0;
virtual bool AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer) = 0;
virtual void DestroySurfaceDescriptor(SurfaceDescriptor* aSurface) = 0;
};
already_AddRefed<gfx::DrawTarget>
GetDrawTargetForDescriptor(const SurfaceDescriptor& aDescriptor, gfx::BackendType aBackend);
already_AddRefed<gfx::DataSourceSurface>
GetSurfaceForDescriptor(const SurfaceDescriptor& aDescriptor);
uint8_t*
GetAddressFromDescriptor(const SurfaceDescriptor& aDescriptor);
class GfxMemoryImageReporter final : public nsIMemoryReporter
{
~GfxMemoryImageReporter() {}
+10 -8
View File
@@ -904,7 +904,8 @@ ImageBridgeChild::AllocShmem(size_t aSize,
{
MOZ_ASSERT(!mShuttingDown);
if (InImageBridgeChildThread()) {
return PImageBridgeChild::AllocShmem(aSize, aType, aShmem);
return PImageBridgeChild::AllocShmem(aSize, aType,
aShmem);
} else {
return DispatchAllocShmemInternal(aSize, aType, aShmem, false); // false: unsafe
}
@@ -929,14 +930,15 @@ static void ProxyAllocShmemNow(AllocShmemParams* aParams,
MOZ_ASSERT(aDone);
MOZ_ASSERT(aBarrier);
auto shmAllocator = aParams->mAllocator->AsShmemAllocator();
if (aParams->mUnsafe) {
aParams->mSuccess = aParams->mAllocator->AllocUnsafeShmem(aParams->mSize,
aParams->mType,
aParams->mShmem);
aParams->mSuccess = shmAllocator->AllocUnsafeShmem(aParams->mSize,
aParams->mType,
aParams->mShmem);
} else {
aParams->mSuccess = aParams->mAllocator->AllocShmem(aParams->mSize,
aParams->mType,
aParams->mShmem);
aParams->mSuccess = shmAllocator->AllocShmem(aParams->mSize,
aParams->mType,
aParams->mShmem);
}
ReentrantMonitorAutoEnter autoMon(*aBarrier);
@@ -978,7 +980,7 @@ static void ProxyDeallocShmemNow(ISurfaceAllocator* aAllocator,
MOZ_ASSERT(aDone);
MOZ_ASSERT(aBarrier);
aAllocator->DeallocShmem(*aShmem);
aAllocator->AsShmemAllocator()->DeallocShmem(*aShmem);
ReentrantMonitorAutoEnter autoMon(*aBarrier);
*aDone = true;
+7 -9
View File
@@ -104,11 +104,14 @@ bool InImageBridgeChildThread();
class ImageBridgeChild final : public PImageBridgeChild
, public CompositableForwarder
, public AsyncTransactionTrackersHolder
, public ShmemAllocator
{
friend class ImageContainer;
typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
public:
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
/**
* Creates the image bridge with a dedicated thread for ImageBridgeChild.
*
@@ -236,7 +239,7 @@ public:
virtual void Connect(CompositableClient* aCompositable,
ImageContainer* aImageContainer) override;
virtual bool IsImageBridgeChild() const override { return true; }
virtual bool UsesImageBridge() const override { return true; }
/**
* See CompositableForwarder::UseTextures
@@ -283,17 +286,12 @@ public:
* call on the ImageBridgeChild thread.
*/
virtual bool AllocUnsafeShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aType,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) override;
/**
* See ISurfaceAllocator.h
* Can be used from any thread.
* If used outside the ImageBridgeChild thread, it will proxy a synchronous
* call on the ImageBridgeChild thread.
*/
virtual bool AllocShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aType,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) override;
/**
* See ISurfaceAllocator.h
* Can be used from any thread.
+2 -6
View File
@@ -350,10 +350,6 @@ ImageBridgeParent::NotifyImageComposites(nsTArray<ImageCompositeNotification>& a
return ok;
}
MessageLoop * ImageBridgeParent::GetMessageLoop() const {
return mMessageLoop;
}
void
ImageBridgeParent::DeferredDestroy()
{
@@ -399,8 +395,8 @@ ImageBridgeParent::OnChannelConnected(int32_t aPid)
bool
ImageBridgeParent::AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
{
if (mStopped) {
return false;
+10 -6
View File
@@ -39,7 +39,8 @@ namespace layers {
* interesting stuff is in ImageContainerParent.
*/
class ImageBridgeParent final : public PImageBridgeParent,
public CompositableParentManager
public CompositableParentManager,
public ShmemAllocator
{
public:
typedef InfallibleTArray<CompositableOperation> EditArray;
@@ -50,6 +51,8 @@ public:
ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport, ProcessId aChildProcessId);
~ImageBridgeParent();
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
static PImageBridgeParent*
@@ -72,8 +75,6 @@ public:
EditReplyArray* aReply) override;
virtual bool RecvUpdateNoSwap(EditArray&& aEdits, OpDestroyArray&& aToDestroy) override;
virtual bool IsAsync() const override { return true; }
PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo,
PImageContainerParent* aImageContainer,
uint64_t*) override;
@@ -97,10 +98,9 @@ public:
// Shutdown step 2
virtual bool RecvStop() override;
virtual MessageLoop* GetMessageLoop() const override;
MessageLoop* GetMessageLoop() const { return mMessageLoop; }
// ISurfaceAllocator
// ShmemAllocator
virtual bool AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
@@ -143,6 +143,10 @@ public:
base::ProcessHandle aPeerProcess,
mozilla::ipc::ProtocolCloneContext* aCtx) override;
virtual bool UsesImageBridge() const override { return true; }
virtual bool IPCOpen() const override { return !mStopped; }
protected:
void OnChannelConnected(int32_t pid) override;
+4 -2
View File
@@ -36,7 +36,8 @@ class CompositableParent;
class ShadowLayersManager;
class LayerTransactionParent final : public PLayerTransactionParent,
public CompositableParentManager
public CompositableParentManager,
public ShmemAllocator
{
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
typedef InfallibleTArray<Edit> EditArray;
@@ -61,7 +62,8 @@ public:
uint64_t GetId() const { return mId; }
Layer* GetRoot() const { return mRoot; }
// ISurfaceAllocator
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
virtual bool AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem) override;
+1 -1
View File
@@ -101,7 +101,7 @@ struct SurfaceDescriptorGralloc {
struct RGBDescriptor {
IntSize size;
SurfaceFormat format;
bool hasInternalBuffer;
bool hasIntermediateBuffer;
};
struct YCbCrDescriptor {
+322 -20
View File
@@ -15,16 +15,18 @@
#include "ShadowLayerChild.h" // for ShadowLayerChild
#include "gfx2DGlue.h" // for Moz2D transition helpers
#include "gfxPlatform.h" // for gfxImageFormat, gfxPlatform
#include "gfxSharedImageSurface.h" // for gfxSharedImageSurface
//#include "gfxSharedImageSurface.h" // for gfxSharedImageSurface
#include "ipc/IPCMessageUtils.h" // for gfxContentType, null_t
#include "IPDLActor.h"
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/layers/CompositableClient.h" // for CompositableClient, etc
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/LayersMessages.h" // for Edit, etc
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG
#include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "ShadowLayerUtils.h"
#include "mozilla/layers/TextureClient.h" // for TextureClient
#include "mozilla/mozalloc.h" // for operator new, etc
@@ -197,6 +199,164 @@ struct AutoTxnEnd {
Transaction* mTxn;
};
// XXX - We should actually figure out the minimum shmem allocation size on
// a certain platform and use that.
const uint32_t sShmemPageSize = 4096;
#ifdef DEBUG
const uint32_t sSupportedBlockSize = 4;
#endif
FixedSizeSmallShmemSectionAllocator::FixedSizeSmallShmemSectionAllocator(ShmemAllocator* aShmProvider)
: mShmProvider(aShmProvider)
{
MOZ_ASSERT(mShmProvider);
}
FixedSizeSmallShmemSectionAllocator::~FixedSizeSmallShmemSectionAllocator()
{
ShrinkShmemSectionHeap();
// Check if we're not leaking..
MOZ_ASSERT(mUsedShmems.empty());
}
bool
FixedSizeSmallShmemSectionAllocator::AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection)
{
// For now we only support sizes of 4. If we want to support different sizes
// some more complicated bookkeeping should be added.
MOZ_ASSERT(aSize == sSupportedBlockSize);
MOZ_ASSERT(aShmemSection);
uint32_t allocationSize = (aSize + sizeof(ShmemSectionHeapAllocation));
for (size_t i = 0; i < mUsedShmems.size(); i++) {
ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
if ((header->mAllocatedBlocks + 1) * allocationSize + sizeof(ShmemSectionHeapHeader) < sShmemPageSize) {
aShmemSection->shmem() = mUsedShmems[i];
MOZ_ASSERT(mUsedShmems[i].IsWritable());
break;
}
}
if (!aShmemSection->shmem().IsWritable()) {
ipc::Shmem tmp;
if (!mShmProvider->AllocUnsafeShmem(sShmemPageSize, OptimalShmemType(), &tmp)) {
return false;
}
ShmemSectionHeapHeader* header = tmp.get<ShmemSectionHeapHeader>();
header->mTotalBlocks = 0;
header->mAllocatedBlocks = 0;
mUsedShmems.push_back(tmp);
aShmemSection->shmem() = tmp;
}
MOZ_ASSERT(aShmemSection->shmem().IsWritable());
ShmemSectionHeapHeader* header = aShmemSection->shmem().get<ShmemSectionHeapHeader>();
uint8_t* heap = aShmemSection->shmem().get<uint8_t>() + sizeof(ShmemSectionHeapHeader);
ShmemSectionHeapAllocation* allocHeader = nullptr;
if (header->mTotalBlocks > header->mAllocatedBlocks) {
// Search for the first available block.
for (size_t i = 0; i < header->mTotalBlocks; i++) {
allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
if (allocHeader->mStatus == STATUS_FREED) {
break;
}
heap += allocationSize;
}
MOZ_ASSERT(allocHeader && allocHeader->mStatus == STATUS_FREED);
MOZ_ASSERT(allocHeader->mSize == sSupportedBlockSize);
} else {
heap += header->mTotalBlocks * allocationSize;
header->mTotalBlocks++;
allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
allocHeader->mSize = aSize;
}
MOZ_ASSERT(allocHeader);
header->mAllocatedBlocks++;
allocHeader->mStatus = STATUS_ALLOCATED;
aShmemSection->size() = aSize;
aShmemSection->offset() = (heap + sizeof(ShmemSectionHeapAllocation)) - aShmemSection->shmem().get<uint8_t>();
ShrinkShmemSectionHeap();
return true;
}
void
FixedSizeSmallShmemSectionAllocator::FreeShmemSection(mozilla::layers::ShmemSection& aShmemSection)
{
MOZ_ASSERT(aShmemSection.size() == sSupportedBlockSize);
MOZ_ASSERT(aShmemSection.offset() < sShmemPageSize - sSupportedBlockSize);
ShmemSectionHeapAllocation* allocHeader =
reinterpret_cast<ShmemSectionHeapAllocation*>(aShmemSection.shmem().get<char>() +
aShmemSection.offset() -
sizeof(ShmemSectionHeapAllocation));
MOZ_ASSERT(allocHeader->mSize == aShmemSection.size());
DebugOnly<bool> success = allocHeader->mStatus.compareExchange(STATUS_ALLOCATED, STATUS_FREED);
// If this fails something really weird is going on.
MOZ_ASSERT(success);
ShmemSectionHeapHeader* header = aShmemSection.shmem().get<ShmemSectionHeapHeader>();
header->mAllocatedBlocks--;
}
void
FixedSizeSmallShmemSectionAllocator::DeallocShmemSection(mozilla::layers::ShmemSection& aShmemSection)
{
FreeShmemSection(aShmemSection);
ShrinkShmemSectionHeap();
}
void
FixedSizeSmallShmemSectionAllocator::ShrinkShmemSectionHeap()
{
// The loop will terminate as we either increase i, or decrease size
// every time through.
size_t i = 0;
while (i < mUsedShmems.size()) {
ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
if (header->mAllocatedBlocks == 0) {
mShmProvider->DeallocShmem(mUsedShmems[i]);
// We don't particularly care about order, move the last one in the array
// to this position.
if (i < mUsedShmems.size() - 1) {
mUsedShmems[i] = mUsedShmems[mUsedShmems.size() - 1];
}
mUsedShmems.pop_back();
} else {
i++;
}
}
}
FixedSizeSmallShmemSectionAllocator*
ShadowLayerForwarder::GetTileLockAllocator()
{
MOZ_ASSERT(IPCOpen());
if (!IPCOpen()) {
return nullptr;
}
if (!mSectionAllocator) {
mSectionAllocator = new FixedSizeSmallShmemSectionAllocator(this);
}
return mSectionAllocator;
}
void
CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier)
{
@@ -206,10 +366,12 @@ CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIden
}
ShadowLayerForwarder::ShadowLayerForwarder()
: mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
: mMessageLoop(MessageLoop::current())
, mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
, mIsFirstPaint(false)
, mWindowOverlayChanged(false)
, mPaintSyncId(0)
, mSectionAllocator(nullptr)
{
mTxn = new Transaction();
}
@@ -225,6 +387,10 @@ ShadowLayerForwarder::~ShadowLayerForwarder()
mShadowManager->SetForwarder(nullptr);
mShadowManager->Destroy();
}
if (mSectionAllocator) {
delete mSectionAllocator;
}
}
void
@@ -415,7 +581,7 @@ ShadowLayerForwarder::UseTextures(CompositableClient* aCompositable,
t.mTimeStamp, t.mPictureRect,
t.mFrameID, t.mProducerID, t.mInputFrameID));
if ((t.mTextureClient->GetFlags() & TextureFlags::IMMEDIATE_UPLOAD)
&& t.mTextureClient->HasInternalBuffer()) {
&& t.mTextureClient->HasIntermediateBuffer()) {
// We use IMMEDIATE_UPLOAD when we want to be sure that the upload cannot
// race with updates on the main thread. In this case we want the transaction
@@ -754,41 +920,40 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
}
bool
ShadowLayerForwarder::AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
ShadowLayerForwarder::AllocUnsafeShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aShmType,
ipc::Shmem* aShmem)
{
MOZ_ASSERT(HasShadowManager(), "no shadow manager");
if (!HasShadowManager() ||
!mShadowManager->IPCOpen()) {
if (!IPCOpen()) {
return false;
}
ShmemAllocated(mShadowManager);
return mShadowManager->AllocShmem(aSize, aType, aShmem);
return mShadowManager->AllocUnsafeShmem(aSize, aShmType, aShmem);
}
bool
ShadowLayerForwarder::AllocUnsafeShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
ShadowLayerForwarder::AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aShmType,
ipc::Shmem* aShmem)
{
MOZ_ASSERT(HasShadowManager(), "no shadow manager");
if (!HasShadowManager() ||
!mShadowManager->IPCOpen()) {
if (!IPCOpen()) {
return false;
}
ShmemAllocated(mShadowManager);
return mShadowManager->AllocUnsafeShmem(aSize, aType, aShmem);
return mShadowManager->AllocShmem(aSize, aShmType, aShmem);
}
void
ShadowLayerForwarder::DeallocShmem(ipc::Shmem& aShmem)
{
MOZ_ASSERT(HasShadowManager(), "no shadow manager");
if (!HasShadowManager() ||
!mShadowManager->IPCOpen()) {
return;
if (HasShadowManager() && mShadowManager->IPCOpen()) {
mShadowManager->DeallocShmem(aShmem);
}
mShadowManager->DeallocShmem(aShmem);
}
bool
@@ -807,7 +972,7 @@ ShadowLayerForwarder::IsSameProcess() const
}
base::ProcessId
ShadowLayerForwarder::ParentPid() const
ShadowLayerForwarder::GetParentPid() const
{
if (!HasShadowManager() || !mShadowManager->IPCOpen()) {
return base::ProcessId();
@@ -947,5 +1112,142 @@ void ShadowLayerForwarder::SendPendingAsyncMessges()
mShadowManager->SendChildAsyncMessages(replies);
}
bool
IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface)
{
return aSurface.type() != SurfaceDescriptor::T__None &&
aSurface.type() != SurfaceDescriptor::Tnull_t;
}
uint8_t*
GetAddressFromDescriptor(const SurfaceDescriptor& aDescriptor)
{
MOZ_ASSERT(IsSurfaceDescriptorValid(aDescriptor));
MOZ_RELEASE_ASSERT(aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer);
auto memOrShmem = aDescriptor.get_SurfaceDescriptorBuffer().data();
if (memOrShmem.type() == MemoryOrShmem::TShmem) {
return memOrShmem.get_Shmem().get<uint8_t>();
} else {
return reinterpret_cast<uint8_t*>(memOrShmem.get_uintptr_t());
}
}
already_AddRefed<gfx::DataSourceSurface>
GetSurfaceForDescriptor(const SurfaceDescriptor& aDescriptor)
{
uint8_t* data = GetAddressFromDescriptor(aDescriptor);
auto rgb = aDescriptor.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
return gfx::Factory::CreateWrappingDataSourceSurface(data, stride, rgb.size(),
rgb.format());
}
already_AddRefed<gfx::DrawTarget>
GetDrawTargetForDescriptor(const SurfaceDescriptor& aDescriptor, gfx::BackendType aBackend)
{
uint8_t* data = GetAddressFromDescriptor(aDescriptor);
auto rgb = aDescriptor.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
return gfx::Factory::CreateDrawTargetForData(gfx::BackendType::CAIRO,
data, rgb.size(),
stride, rgb.format());
}
bool
ShadowLayerForwarder::AllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
SurfaceDescriptor* aBuffer)
{
if (!IPCOpen()) {
return false;
}
return AllocSurfaceDescriptorWithCaps(aSize, aContent, DEFAULT_BUFFER_CAPS, aBuffer);
}
bool
ShadowLayerForwarder::AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer)
{
if (!IPCOpen()) {
return false;
}
gfx::SurfaceFormat format =
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aContent);
size_t size = ImageDataSerializer::ComputeRGBBufferSize(aSize, format);
if (!size) {
return false;
}
MemoryOrShmem bufferDesc;
if (IsSameProcess()) {
uint8_t* data = new (std::nothrow) uint8_t[size];
if (!data) {
return false;
}
GfxMemoryImageReporter::DidAlloc(data);
#ifdef XP_MACOSX
// Workaround a bug in Quartz where drawing an a8 surface to another a8
// surface with OP_SOURCE still requires the destination to be clear.
if (format == gfx::SurfaceFormat::A8) {
memset(data, 0, size);
}
#endif
bufferDesc = reinterpret_cast<uintptr_t>(data);
} else {
mozilla::ipc::Shmem shmem;
if (!AllocUnsafeShmem(size, OptimalShmemType(), &shmem)) {
return false;
}
bufferDesc = shmem;
}
// Use an intermediate buffer by default. Skipping the intermediate buffer is
// only possible in certain configurations so let's keep it simple here for now.
const bool hasIntermediateBuffer = true;
*aBuffer = SurfaceDescriptorBuffer(RGBDescriptor(aSize, format, hasIntermediateBuffer),
bufferDesc);
return true;
}
/* static */ bool
ShadowLayerForwarder::IsShmem(SurfaceDescriptor* aSurface)
{
return aSurface && (aSurface->type() == SurfaceDescriptor::TSurfaceDescriptorBuffer)
&& (aSurface->get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::TShmem);
}
void
ShadowLayerForwarder::DestroySurfaceDescriptor(SurfaceDescriptor* aSurface)
{
MOZ_ASSERT(aSurface);
MOZ_ASSERT(IPCOpen());
if (!IPCOpen() || !aSurface) {
return;
}
SurfaceDescriptorBuffer& desc = aSurface->get_SurfaceDescriptorBuffer();
switch (desc.data().type()) {
case MemoryOrShmem::TShmem: {
DeallocShmem(desc.data().get_Shmem());
break;
}
case MemoryOrShmem::Tuintptr_t: {
uint8_t* ptr = (uint8_t*)desc.data().get_uintptr_t();
GfxMemoryImageReporter::WillFree(ptr);
delete [] ptr;
break;
}
default:
NS_RUNTIMEABORT("surface type not implemented!");
}
*aSurface = SurfaceDescriptor();
}
} // namespace layers
} // namespace mozilla
+79 -3
View File
@@ -22,11 +22,13 @@
#include "nsRegion.h" // for nsIntRegion
#include "nsTArrayForwardDeclare.h" // for InfallibleTArray
#include "nsIWidget.h"
#include <vector>
namespace mozilla {
namespace layers {
class EditReply;
class FixedSizeSmallShmemSectionAllocator;
class ImageContainer;
class Layer;
class PLayerChild;
@@ -39,7 +41,6 @@ class ThebesBuffer;
class ThebesBufferData;
class Transaction;
/**
* We want to share layer trees across thread contexts and address
* spaces for several reasons; chief among them
@@ -114,12 +115,23 @@ class Transaction;
*/
class ShadowLayerForwarder final : public CompositableForwarder
, public ShmemAllocator
, public LegacySurfaceDescriptorAllocator
{
friend class ClientLayerManager;
public:
virtual ~ShadowLayerForwarder();
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
virtual ShadowLayerForwarder* AsLayerForwarder() override { return this; }
virtual LegacySurfaceDescriptorAllocator*
AsLegacySurfaceDescriptorAllocator() override { return this; }
FixedSizeSmallShmemSectionAllocator* GetTileLockAllocator();
/**
* Setup the IPDL actor for aCompositable to be part of layers
* transactions.
@@ -322,7 +334,7 @@ public:
* buffer, and the double-buffer pair is gone.
*/
// ISurfaceAllocator
virtual bool AllocUnsafeShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aType,
mozilla::ipc::Shmem* aShmem) override;
@@ -332,8 +344,12 @@ public:
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
virtual bool IPCOpen() const override;
virtual bool IsSameProcess() const override;
virtual base::ProcessId ParentPid() const override;
virtual MessageLoop* GetMessageLoop() const override { return mMessageLoop; }
base::ProcessId GetParentPid() const;
/**
* Construct a shadow of |aLayer| on the "other side", at the
@@ -350,6 +366,20 @@ public:
static void PlatformSyncBeforeUpdate();
virtual bool AllocSurfaceDescriptor(const gfx::IntSize& aSize,
gfxContentType aContent,
SurfaceDescriptor* aBuffer) override;
virtual bool AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer) override;
virtual void DestroySurfaceDescriptor(SurfaceDescriptor* aSurface) override;
// Returns true if aSurface wraps a Shmem.
static bool IsShmem(SurfaceDescriptor* aSurface);
protected:
ShadowLayerForwarder();
@@ -366,12 +396,14 @@ protected:
private:
Transaction* mTxn;
MessageLoop* mMessageLoop;
std::vector<AsyncChildMessageData> mPendingAsyncMessages;
DiagnosticTypes mDiagnosticTypes;
bool mIsFirstPaint;
bool mWindowOverlayChanged;
int32_t mPaintSyncId;
InfallibleTArray<PluginWindowData> mPluginWindowData;
FixedSizeSmallShmemSectionAllocator* mSectionAllocator;
};
class CompositableClient;
@@ -408,6 +440,50 @@ protected:
PLayerChild* mShadow;
};
/// A simple shmem section allocator that can only allocate small
/// fixed size elements (only intended to be used to store tile
/// copy-on-write locks for now).
class FixedSizeSmallShmemSectionAllocator final : public ShmemSectionAllocator
{
public:
enum AllocationStatus
{
STATUS_ALLOCATED,
STATUS_FREED
};
struct ShmemSectionHeapHeader
{
Atomic<uint32_t> mTotalBlocks;
Atomic<uint32_t> mAllocatedBlocks;
};
struct ShmemSectionHeapAllocation
{
Atomic<uint32_t> mStatus;
uint32_t mSize;
};
explicit FixedSizeSmallShmemSectionAllocator(ShmemAllocator* aShmProvider);
~FixedSizeSmallShmemSectionAllocator();
virtual bool AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection) override;
virtual void DeallocShmemSection(ShmemSection& aShmemSection) override;
virtual void MemoryPressure() override { ShrinkShmemSectionHeap(); }
// can be called on the compositor process.
static void FreeShmemSection(ShmemSection& aShmemSection);
void ShrinkShmemSectionHeap();
protected:
std::vector<mozilla::ipc::Shmem> mUsedShmems;
ShmemAllocator* mShmProvider;
};
} // namespace layers
} // namespace mozilla
+15 -14
View File
@@ -11,6 +11,7 @@
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "gfx2DGlue.h"
#include "gfxPrefs.h" // for gfxPrefs
#include "SharedSurfaceGralloc.h"
@@ -109,11 +110,11 @@ GrallocTextureData::~GrallocTextureData()
}
void
GrallocTextureData::Deallocate(ISurfaceAllocator* aAllocator)
GrallocTextureData::Deallocate(ClientIPCAllocator* aAllocator)
{
MOZ_ASSERT(aAllocator);
if (aAllocator) {
aAllocator->DeallocGrallocBuffer(&mGrallocHandle);
if (aAllocator && aAllocator->IPCOpen()) {
SharedBufferManagerChild::GetSingleton()->DeallocGrallocBuffer(mGrallocHandle);
}
mGrallocHandle = null_t();
@@ -121,11 +122,11 @@ GrallocTextureData::Deallocate(ISurfaceAllocator* aAllocator)
}
void
GrallocTextureData::Forget(ISurfaceAllocator* aAllocator)
GrallocTextureData::Forget(ClientIPCAllocator* aAllocator)
{
MOZ_ASSERT(aAllocator);
if (aAllocator) {
aAllocator->DropGrallocBuffer(&mGrallocHandle);
if (aAllocator && aAllocator->IPCOpen()) {
SharedBufferManagerChild::GetSingleton()->DropGrallocBuffer(mGrallocHandle);
}
mGrallocHandle = null_t();
@@ -278,12 +279,12 @@ GrallocTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
GrallocTextureData*
GrallocTextureData::Create(gfx::IntSize aSize, AndroidFormat aAndroidFormat,
gfx::BackendType aMoz2dBackend, uint32_t aUsage,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
if (!aAllocator) {
if (!aAllocator || !aAllocator->IPCOpen()) {
return nullptr;
}
int32_t maxSize = aAllocator->GetMaxTextureSize();
int32_t maxSize = aAllocator->AsClientAllocator()->GetMaxTextureSize();
if (aSize.width > maxSize || aSize.height > maxSize) {
return nullptr;
}
@@ -313,7 +314,7 @@ GrallocTextureData::Create(gfx::IntSize aSize, AndroidFormat aAndroidFormat,
}
MaybeMagicGrallocBufferHandle handle;
if (!aAllocator->AllocGrallocBuffer(aSize, aAndroidFormat, aUsage, &handle)) {
if (!SharedBufferManagerChild::GetSingleton()->AllocGrallocBuffer(aSize, aAndroidFormat, aUsage, &handle)) {
return nullptr;
}
@@ -333,7 +334,7 @@ GrallocTextureData::Create(gfx::IntSize aSize, AndroidFormat aAndroidFormat,
GrallocTextureData*
GrallocTextureData::CreateForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aMoz2dBackend,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
if (DisableGralloc(aFormat, aSize)) {
return nullptr;
@@ -385,7 +386,7 @@ GrallocTextureData::GetTextureFlags() const
// static
GrallocTextureData*
GrallocTextureData::CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
MOZ_ASSERT(aYSize.width == aCbCrSize.width * 2);
MOZ_ASSERT(aYSize.height == aCbCrSize.height * 2);
@@ -398,7 +399,7 @@ GrallocTextureData::CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
// static
GrallocTextureData*
GrallocTextureData::CreateForGLRendering(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
ISurfaceAllocator* aAllocator)
ClientIPCAllocator* aAllocator)
{
if (aFormat == gfx::SurfaceFormat::YUV) {
return nullptr;
@@ -434,7 +435,7 @@ GrallocTextureData::TextureClientFromSharedSurface(gl::SharedSurface* abstractSu
}
TextureData*
GrallocTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
GrallocTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const
{
+8 -9
View File
@@ -8,7 +8,6 @@
#ifdef MOZ_WIDGET_GONK
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/ISurfaceAllocator.h" // For IsSurfaceDescriptorValid
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
#include <ui/GraphicBuffer.h>
@@ -58,34 +57,34 @@ public:
virtual bool SupportsMoz2D() const override { return true; }
virtual bool HasInternalBuffer() const override { return false; }
virtual bool HasIntermediateBuffer() const override { return false; }
virtual bool HasSynchronization() const override { return true; }
virtual void Deallocate(ISurfaceAllocator*) override;
virtual void Deallocate(ClientIPCAllocator*) override;
virtual void Forget(ISurfaceAllocator*) override;
virtual void Forget(ClientIPCAllocator*) override;
static GrallocTextureData* CreateForDrawing(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aMoz2dBackend,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
static GrallocTextureData* CreateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbCrSize,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
static GrallocTextureData* CreateForGLRendering(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
static GrallocTextureData* Create(gfx::IntSize aSize, AndroidFormat aFormat,
gfx::BackendType aMoz2DBackend, uint32_t aUsage,
ISurfaceAllocator* aAllocator);
ClientIPCAllocator* aAllocator);
static already_AddRefed<TextureClient>
TextureClientFromSharedSurface(gl::SharedSurface* abstractSurf, TextureFlags flags);
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
CreateSimilar(ClientIPCAllocator* aAllocator,
TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
@@ -30,11 +30,11 @@ public:
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual bool HasInternalBuffer() const override { return false; }
virtual bool HasIntermediateBuffer() const override { return false; }
virtual void Deallocate(ISurfaceAllocator* aAllocator) override { mSurface = nullptr; }
virtual void Deallocate(ClientIPCAllocator*) override { mSurface = nullptr; }
virtual void Forget(ISurfaceAllocator* aAllocator) override { mSurface = nullptr; }
virtual void Forget(ClientIPCAllocator*) override { mSurface = nullptr; }
// For debugging purposes only.
already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
+2 -2
View File
@@ -29,7 +29,7 @@ EGLImageTextureData::EGLImageTextureData(EGLImageImage* aImage, gfx::IntSize aSi
already_AddRefed<TextureClient>
EGLImageTextureData::CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
ISurfaceAllocator* aAllocator, TextureFlags aFlags)
ClientIPCAllocator* aAllocator, TextureFlags aFlags)
{
MOZ_ASSERT(XRE_IsParentProcess(),
"Can't pass an `EGLImage` between processes.");
@@ -71,7 +71,7 @@ already_AddRefed<TextureClient>
AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTexture* aSurfTex,
gfx::IntSize aSize,
gl::OriginPos aOriginPos,
ISurfaceAllocator* aAllocator,
ClientIPCAllocator* aAllocator,
TextureFlags aFlags)
{
MOZ_ASSERT(XRE_IsParentProcess(),
+7 -7
View File
@@ -26,17 +26,17 @@ public:
static already_AddRefed<TextureClient>
CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
ISurfaceAllocator* aAllocator, TextureFlags aFlags);
ClientIPCAllocator* aAllocator, TextureFlags aFlags);
virtual bool HasInternalBuffer() const override { return false; }
virtual bool HasIntermediateBuffer() const override { return false; }
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual void Deallocate(ISurfaceAllocator*) override { mImage = nullptr; }
virtual void Deallocate(ClientIPCAllocator*) override { mImage = nullptr; }
virtual void Forget(ISurfaceAllocator*) override { mImage = nullptr; }
virtual void Forget(ClientIPCAllocator*) override { mImage = nullptr; }
// Unused functions.
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
@@ -64,12 +64,12 @@ public:
CreateTextureClient(gl::AndroidSurfaceTexture* aSurfTex,
gfx::IntSize aSize,
gl::OriginPos aOriginPos,
ISurfaceAllocator* aAllocator,
ClientIPCAllocator* aAllocator,
TextureFlags aFlags);
~AndroidSurfaceTextureData();
virtual bool HasInternalBuffer() const override { return false; }
virtual bool HasIntermediateBuffer() const override { return false; }
virtual gfx::IntSize GetSize() const override { return mSize; }
@@ -86,7 +86,7 @@ public:
}
// Our data is always owned externally.
virtual void Deallocate(ISurfaceAllocator*) override {}
virtual void Deallocate(ClientIPCAllocator*) override {}
protected:
AndroidSurfaceTextureData(gl::AndroidSurfaceTexture* aSurfTex,
+6
View File
@@ -818,7 +818,9 @@ gfxContext::PushGroupForBlendBack(gfxContentType content, Float aOpacity, Source
CurrentState().mBlendOpacity = aOpacity;
CurrentState().mBlendMask = aMask;
#ifdef DEBUG
CurrentState().mWasPushedForBlendBack = true;
#endif
CurrentState().mBlendMaskTransform = aMaskTransform;
}
}
@@ -870,7 +872,9 @@ gfxContext::PushGroupAndCopyBackground(gfxContentType content, Float aOpacity, S
CurrentState().mBlendOpacity = aOpacity;
CurrentState().mBlendMask = aMask;
#ifdef DEBUG
CurrentState().mWasPushedForBlendBack = true;
#endif
CurrentState().mBlendMaskTransform = aMaskTransform;
Point offset = CurrentState().deviceOffset - oldDeviceOffset;
@@ -918,7 +922,9 @@ gfxContext::PushGroupAndCopyBackground(gfxContentType content, Float aOpacity, S
mDT->SetTransform(GetDTTransform());
CurrentState().mBlendOpacity = aOpacity;
CurrentState().mBlendMask = aMask;
#ifdef DEBUG
CurrentState().mWasPushedForBlendBack = true;
#endif
CurrentState().mBlendMaskTransform = aMaskTransform;
}
}
+3 -1
View File
@@ -506,7 +506,9 @@ private:
mozilla::gfx::Float mBlendOpacity;
RefPtr<SourceSurface> mBlendMask;
Matrix mBlendMaskTransform;
mozilla::DebugOnly<bool> mWasPushedForBlendBack;
#ifdef DEBUG
bool mWasPushedForBlendBack;
#endif
};
// This ensures mPath contains a valid path (in user space!)
@@ -38,7 +38,7 @@ gfxReusableSharedImageSurfaceWrapper::ReadUnlock()
MOZ_ASSERT(readCount >= 0, "Read count should not be negative");
if (readCount == 0) {
mAllocator->DeallocShmem(mSurface->GetShmem());
mAllocator->AsShmemAllocator()->DeallocShmem(mSurface->GetShmem());
}
}
@@ -56,7 +56,7 @@ gfxReusableSharedImageSurfaceWrapper::GetWritable(gfxImageSurface** aSurface)
// Something else is reading the surface, copy it
RefPtr<gfxSharedImageSurface> copySurface =
gfxSharedImageSurface::CreateUnsafe(mAllocator.get(), mSurface->GetSize(), mSurface->Format());
gfxSharedImageSurface::CreateUnsafe(mAllocator->AsShmemAllocator(), mSurface->GetSize(), mSurface->Format());
copySurface->CopyFrom(mSurface);
*aSurface = copySurface;
+1
View File
@@ -351,6 +351,7 @@ pref("media.use-blank-decoder", false);
pref("media.wmf.enabled", true);
pref("media.wmf.decoder.thread-count", -1);
pref("media.wmf.low-latency.enabled", false);
pref("media.wmf.skip-blacklist", false);
#endif
#if defined(MOZ_FFMPEG)
pref("media.ffmpeg.enabled", true);
+2 -2
View File
@@ -2109,7 +2109,7 @@ nsIWidget::SnapshotWidgetOnScreen()
RefPtr<gfx::DrawTarget> dt =
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(size, gfx::SurfaceFormat::B8G8R8A8);
if (!snapshot || !dt) {
forwarder->DestroySharedSurface(&surface);
forwarder->DestroySurfaceDescriptor(&surface);
return nullptr;
}
@@ -2118,7 +2118,7 @@ nsIWidget::SnapshotWidgetOnScreen()
gfx::Rect(gfx::Point(), gfx::Size(size)),
gfx::DrawSurfaceOptions(gfx::Filter::POINT));
forwarder->DestroySharedSurface(&surface);
forwarder->DestroySurfaceDescriptor(&surface);
return dt->Snapshot();
}