2017-02-13 19:51:00 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2017-02-13 20:20:00 +03:00
|
|
|
#include "gfxImageSurface.h"
|
2017-02-13 19:51:00 +03:00
|
|
|
#include "gfxPlatform.h"
|
|
|
|
#include "mozilla/layers/BufferTexture.h"
|
|
|
|
#include "mozilla/layers/LayersTypes.h"
|
|
|
|
#include "mozilla/layers/TextureClient.h"
|
|
|
|
#include "mozilla/layers/TextureHost.h"
|
|
|
|
#include "mozilla/RefPtr.h"
|
2017-02-13 20:20:00 +03:00
|
|
|
#ifdef XP_WIN
|
|
|
|
# include "IMFYCbCrImage.h"
|
|
|
|
# include "mozilla/gfx/DeviceManagerDx.h"
|
2018-06-28 06:56:36 +03:00
|
|
|
# include "mozilla/layers/D3D11YCbCrImage.h"
|
2017-02-13 20:20:00 +03:00
|
|
|
# include "mozilla/layers/TextureD3D11.h"
|
|
|
|
# include "mozilla/layers/TextureDIB.h"
|
|
|
|
#endif
|
2017-02-13 19:51:00 +03:00
|
|
|
|
|
|
|
using mozilla::gfx::SurfaceFormat;
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a YCbCrTextureClient according to the given backend.
|
|
|
|
*/
|
|
|
|
static already_AddRefed<TextureClient> CreateYCbCrTextureClientWithBackend(
|
|
|
|
LayersBackend aLayersBackend) {
|
2017-02-13 20:20:00 +03:00
|
|
|
TextureData* data = nullptr;
|
|
|
|
IntSize size = IntSize(200, 150);
|
|
|
|
IntSize ySize = IntSize(400, 300);
|
|
|
|
|
|
|
|
RefPtr<gfxImageSurface> ySurface =
|
|
|
|
new gfxImageSurface(ySize, SurfaceFormat::A8);
|
|
|
|
RefPtr<gfxImageSurface> cbSurface =
|
|
|
|
new gfxImageSurface(size, SurfaceFormat::A8);
|
|
|
|
RefPtr<gfxImageSurface> crSurface =
|
|
|
|
new gfxImageSurface(size, SurfaceFormat::A8);
|
|
|
|
|
|
|
|
PlanarYCbCrData clientData;
|
|
|
|
clientData.mYChannel = ySurface->Data();
|
|
|
|
clientData.mCbChannel = cbSurface->Data();
|
|
|
|
clientData.mCrChannel = crSurface->Data();
|
|
|
|
clientData.mYSize = ySurface->GetSize();
|
|
|
|
clientData.mPicSize = ySurface->GetSize();
|
|
|
|
clientData.mCbCrSize = cbSurface->GetSize();
|
|
|
|
clientData.mYStride = ySurface->Stride();
|
|
|
|
clientData.mCbCrStride = cbSurface->Stride();
|
|
|
|
clientData.mStereoMode = StereoMode::MONO;
|
|
|
|
clientData.mYSkip = 0;
|
|
|
|
clientData.mCbSkip = 0;
|
|
|
|
clientData.mCrSkip = 0;
|
|
|
|
clientData.mCrSkip = 0;
|
|
|
|
clientData.mPicX = 0;
|
|
|
|
clientData.mPicX = 0;
|
|
|
|
|
2018-09-25 23:44:55 +03:00
|
|
|
// Create YCbCrTexture for basic backend.
|
2017-02-13 20:20:00 +03:00
|
|
|
if (aLayersBackend == LayersBackend::LAYERS_BASIC) {
|
2017-09-29 17:37:56 +03:00
|
|
|
return TextureClient::CreateForYCbCr(
|
|
|
|
nullptr, clientData.mYSize, clientData.mYStride, clientData.mCbCrSize,
|
2018-09-25 23:44:55 +03:00
|
|
|
clientData.mCbCrStride, StereoMode::MONO, gfx::ColorDepth::COLOR_8,
|
2019-07-26 11:45:31 +03:00
|
|
|
gfx::YUVColorSpace::BT601, gfx::ColorRange::LIMITED,
|
|
|
|
TextureFlags::DEALLOCATE_CLIENT);
|
2017-02-13 20:20:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
2018-06-28 06:56:36 +03:00
|
|
|
RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetImageDevice();
|
2017-02-13 20:20:00 +03:00
|
|
|
|
2017-03-08 11:17:36 +03:00
|
|
|
if (device && aLayersBackend == LayersBackend::LAYERS_D3D11) {
|
2018-06-28 06:56:36 +03:00
|
|
|
DXGIYCbCrTextureAllocationHelper helper(clientData, TextureFlags::DEFAULT,
|
|
|
|
device);
|
|
|
|
RefPtr<TextureClient> texture = helper.Allocate(nullptr);
|
|
|
|
return texture.forget();
|
2017-02-13 20:20:00 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
return MakeAndAddRef<TextureClient>(data, TextureFlags::DEALLOCATE_CLIENT,
|
|
|
|
nullptr);
|
|
|
|
}
|
|
|
|
|
2017-02-13 19:51:00 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a TextureClient according to the given backend.
|
|
|
|
*/
|
|
|
|
static already_AddRefed<TextureClient> CreateTextureClientWithBackend(
|
|
|
|
LayersBackend aLayersBackend) {
|
2017-02-13 20:20:00 +03:00
|
|
|
TextureData* data = nullptr;
|
|
|
|
SurfaceFormat format = gfxPlatform::GetPlatform()->Optimal2DFormatForContent(
|
|
|
|
gfxContentType::COLOR_ALPHA);
|
|
|
|
BackendType moz2DBackend =
|
|
|
|
gfxPlatform::GetPlatform()->GetContentBackendFor(aLayersBackend);
|
|
|
|
TextureAllocationFlags allocFlags = TextureAllocationFlags::ALLOC_DEFAULT;
|
|
|
|
IntSize size = IntSize(400, 300);
|
|
|
|
TextureFlags textureFlags = TextureFlags::DEALLOCATE_CLIENT;
|
|
|
|
|
|
|
|
if (!gfx::Factory::AllowedSurfaceSize(size)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
if (aLayersBackend == LayersBackend::LAYERS_D3D11 &&
|
|
|
|
(moz2DBackend == BackendType::DIRECT2D ||
|
|
|
|
moz2DBackend == BackendType::DIRECT2D1_1)) {
|
2019-04-11 15:38:59 +03:00
|
|
|
// Create D3D11TextureData.
|
|
|
|
data = D3D11TextureData::Create(size, format, allocFlags);
|
2017-02-13 20:20:00 +03:00
|
|
|
} else if (!data && format == SurfaceFormat::B8G8R8X8 &&
|
|
|
|
moz2DBackend == BackendType::CAIRO) {
|
|
|
|
// Create DIBTextureData.
|
|
|
|
data = DIBTextureData::Create(size, format, nullptr);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!data && aLayersBackend == LayersBackend::LAYERS_BASIC) {
|
|
|
|
// Create BufferTextureData.
|
|
|
|
data = BufferTextureData::Create(size, format, moz2DBackend, aLayersBackend,
|
|
|
|
textureFlags, allocFlags, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
return MakeAndAddRef<TextureClient>(data, textureFlags, nullptr);
|
|
|
|
}
|
|
|
|
|
2017-02-13 19:51:00 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a TextureHost according to the given TextureClient.
|
|
|
|
*/
|
2017-02-13 20:20:00 +03:00
|
|
|
already_AddRefed<TextureHost> CreateTextureHostWithBackend(
|
2018-02-07 17:33:12 +03:00
|
|
|
TextureClient* aClient, ISurfaceAllocator* aDeallocator,
|
2017-02-13 20:20:00 +03:00
|
|
|
LayersBackend& aLayersBackend) {
|
2017-02-13 19:51:00 +03:00
|
|
|
if (!aClient) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// client serialization
|
|
|
|
SurfaceDescriptor descriptor;
|
2018-03-12 16:10:13 +03:00
|
|
|
ReadLockDescriptor readLock = null_t();
|
2017-02-13 19:51:00 +03:00
|
|
|
RefPtr<TextureHost> textureHost;
|
|
|
|
|
|
|
|
aClient->ToSurfaceDescriptor(descriptor);
|
|
|
|
|
2017-04-20 04:24:13 +03:00
|
|
|
wr::MaybeExternalImageId id = Nothing();
|
2018-03-12 16:10:13 +03:00
|
|
|
return TextureHost::Create(descriptor, readLock, aDeallocator, aLayersBackend,
|
2017-04-20 04:24:13 +03:00
|
|
|
aClient->GetFlags(), id);
|
2017-02-13 19:51:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|