mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 13:23:07 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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, ©Rect, mSyncSurface, ©Rect, 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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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!");
|
||||
|
||||
@@ -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)
|
||||
{ }
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -538,7 +538,7 @@ ClientLayerManager::MakeSnapshotIfRequired()
|
||||
DrawOptions(1.0f, CompositionOp::OP_OVER));
|
||||
dt->SetTransform(oldMatrix);
|
||||
}
|
||||
mForwarder->DestroySharedSurface(&inSnapshot);
|
||||
mForwarder->DestroySurfaceDescriptor(&inSnapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -97,7 +97,7 @@ private:
|
||||
};
|
||||
|
||||
public:
|
||||
explicit gfxShmSharedReadLock(ISurfaceAllocator* aAllocator);
|
||||
explicit gfxShmSharedReadLock(ClientIPCAllocator* aAllocator);
|
||||
|
||||
protected:
|
||||
~gfxShmSharedReadLock();
|
||||
|
||||
@@ -108,7 +108,7 @@ ImageHost::SetCurrentTextureHost(TextureHost* aTexture)
|
||||
}
|
||||
|
||||
bool swapTextureSources = !!mCurrentTextureHost && !!mCurrentTextureSource
|
||||
&& mCurrentTextureHost->HasInternalBuffer();
|
||||
&& mCurrentTextureHost->HasIntermediateBuffer();
|
||||
|
||||
if (swapTextureSources) {
|
||||
auto dataSource = mCurrentTextureSource->AsDataTextureSource();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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(®ion);
|
||||
#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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -101,7 +101,7 @@ struct SurfaceDescriptorGralloc {
|
||||
struct RGBDescriptor {
|
||||
IntSize size;
|
||||
SurfaceFormat format;
|
||||
bool hasInternalBuffer;
|
||||
bool hasIntermediateBuffer;
|
||||
};
|
||||
|
||||
struct YCbCrDescriptor {
|
||||
|
||||
+322
-20
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,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();
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user