mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-27 19:07:31 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
c889903081
34 changed files with 846 additions and 195 deletions
|
|
@ -9,9 +9,16 @@
|
|||
#include "ImageContainer.h"
|
||||
#include "mozilla/layers/SharedRGBImage.h"
|
||||
#include "YCbCrUtils.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/layers/KnowsCompositor.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include "mozilla/layers/D3D11YCbCrImage.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
|
@ -218,19 +225,14 @@ VideoData::ShallowCopyUpdateTimestampAndDuration(const VideoData* aOther,
|
|||
return v.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
||||
const VideoInfo& aInfo,
|
||||
const YCbCrBuffer &aBuffer,
|
||||
const IntRect& aPicture,
|
||||
bool aCopyData)
|
||||
PlanarYCbCrData
|
||||
ConstructPlanarYCbCrData(const VideoInfo& aInfo,
|
||||
const VideoData::YCbCrBuffer& aBuffer,
|
||||
const IntRect& aPicture)
|
||||
{
|
||||
if (!aVideoImage) {
|
||||
return false;
|
||||
}
|
||||
const YCbCrBuffer::Plane &Y = aBuffer.mPlanes[0];
|
||||
const YCbCrBuffer::Plane &Cb = aBuffer.mPlanes[1];
|
||||
const YCbCrBuffer::Plane &Cr = aBuffer.mPlanes[2];
|
||||
const VideoData::YCbCrBuffer::Plane& Y = aBuffer.mPlanes[0];
|
||||
const VideoData::YCbCrBuffer::Plane& Cb = aBuffer.mPlanes[1];
|
||||
const VideoData::YCbCrBuffer::Plane& Cr = aBuffer.mPlanes[2];
|
||||
|
||||
PlanarYCbCrData data;
|
||||
data.mYChannel = Y.mData + Y.mOffset;
|
||||
|
|
@ -249,6 +251,21 @@ bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
|||
data.mStereoMode = aInfo.mStereoMode;
|
||||
data.mYUVColorSpace = aBuffer.mYUVColorSpace;
|
||||
data.mColorRange = aBuffer.mColorRange;
|
||||
return data;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
||||
const VideoInfo& aInfo,
|
||||
const YCbCrBuffer &aBuffer,
|
||||
const IntRect& aPicture,
|
||||
bool aCopyData)
|
||||
{
|
||||
if (!aVideoImage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
|
||||
|
||||
aVideoImage->SetDelayedConversion(true);
|
||||
if (aCopyData) {
|
||||
|
|
@ -268,7 +285,8 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo,
|
|||
const YCbCrBuffer& aBuffer,
|
||||
bool aKeyframe,
|
||||
int64_t aTimecode,
|
||||
const IntRect& aPicture)
|
||||
const IntRect& aPicture,
|
||||
layers::KnowsCompositor* aAllocator)
|
||||
{
|
||||
if (!aContainer) {
|
||||
// Create a dummy VideoData with no image. This gives us something to
|
||||
|
|
@ -296,6 +314,23 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo,
|
|||
0));
|
||||
// Currently our decoder only knows how to output to ImageFormat::PLANAR_YCBCR
|
||||
// format.
|
||||
#if XP_WIN
|
||||
// We disable this code path on Windows 7 due to intermittent crashes with old drivers.
|
||||
// See Mozilla bug 1405110.
|
||||
if (IsWin8OrLater() && !XRE_IsParentProcess() &&
|
||||
aAllocator && aAllocator->GetCompositorBackendType()
|
||||
== layers::LayersBackend::LAYERS_D3D11) {
|
||||
RefPtr<layers::D3D11YCbCrImage> d3d11Image = new layers::D3D11YCbCrImage();
|
||||
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
|
||||
if (d3d11Image->SetData(layers::ImageBridgeChild::GetSingleton()
|
||||
? layers::ImageBridgeChild::GetSingleton().get()
|
||||
: aAllocator,
|
||||
aContainer, data)) {
|
||||
v->mImage = d3d11Image;
|
||||
return v.forget();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!v->mImage) {
|
||||
v->mImage = aContainer->CreatePlanarYCbCrImage();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace mozilla {
|
|||
namespace layers {
|
||||
class Image;
|
||||
class ImageContainer;
|
||||
class KnowsCompositor;
|
||||
} // namespace layers
|
||||
|
||||
class MediaByteBuffer;
|
||||
|
|
@ -472,7 +473,8 @@ public:
|
|||
const YCbCrBuffer &aBuffer,
|
||||
bool aKeyframe,
|
||||
int64_t aTimecode,
|
||||
const IntRect& aPicture);
|
||||
const IntRect& aPicture,
|
||||
layers::KnowsCompositor* aAllocator = nullptr);
|
||||
|
||||
static already_AddRefed<VideoData> CreateAndCopyData(const VideoInfo& aInfo,
|
||||
ImageContainer* aContainer,
|
||||
|
|
|
|||
|
|
@ -1500,6 +1500,15 @@ MediaFormatReader::Update(TrackType aTrack)
|
|||
nsCString error;
|
||||
mVideo.mIsHardwareAccelerated =
|
||||
mVideo.mDecoder && mVideo.mDecoder->IsHardwareAccelerated(error);
|
||||
#ifdef XP_WIN
|
||||
// D3D11_YCBCR_IMAGE images are GPU based, we try to limit the amount
|
||||
// of GPU RAM used.
|
||||
VideoData* videoData = static_cast<VideoData*>(output.get());
|
||||
mVideo.mIsHardwareAccelerated =
|
||||
mVideo.mIsHardwareAccelerated ||
|
||||
(videoData->mImage &&
|
||||
videoData->mImage->GetFormat() == ImageFormat::D3D11_YCBCR_IMAGE);
|
||||
#endif
|
||||
}
|
||||
} else if (decoder.HasFatalError()) {
|
||||
LOG("Rejecting %s promise: DECODE_ERROR", TrackTypeToStr(aTrack));
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ ogg_packet InitTheoraPacket(const unsigned char* aData, size_t aLength,
|
|||
}
|
||||
|
||||
TheoraDecoder::TheoraDecoder(const CreateDecoderParams& aParams)
|
||||
: mImageContainer(aParams.mImageContainer)
|
||||
: mImageAllocator(aParams.mKnowsCompositor)
|
||||
, mImageContainer(aParams.mImageContainer)
|
||||
, mTaskQueue(aParams.mTaskQueue)
|
||||
, mCallback(aParams.mCallback)
|
||||
, mIsFlushing(false)
|
||||
|
|
@ -176,7 +177,8 @@ TheoraDecoder::DoDecode(MediaRawData* aSample)
|
|||
aSample->mKeyframe,
|
||||
aSample->mTimecode,
|
||||
mInfo.ScaledImageRect(mTheoraInfo.frame_width,
|
||||
mTheoraInfo.frame_height));
|
||||
mTheoraInfo.frame_height),
|
||||
mImageAllocator);
|
||||
if (!v) {
|
||||
LOG("Image allocation error source %ldx%ld display %ldx%ld picture %ldx%ld",
|
||||
mTheoraInfo.frame_width, mTheoraInfo.frame_height, mInfo.mDisplay.width, mInfo.mDisplay.height,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ private:
|
|||
MediaResult DoDecode(MediaRawData* aSample);
|
||||
void ProcessDrain();
|
||||
|
||||
RefPtr<KnowsCompositor> mImageAllocator;
|
||||
RefPtr<ImageContainer> mImageContainer;
|
||||
RefPtr<TaskQueue> mTaskQueue;
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ InitContext(vpx_codec_ctx_t* aCtx,
|
|||
|
||||
VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams)
|
||||
: mImageContainer(aParams.mImageContainer)
|
||||
, mImageAllocator(aParams.mKnowsCompositor)
|
||||
, mTaskQueue(aParams.mTaskQueue)
|
||||
, mCallback(aParams.mCallback)
|
||||
, mIsFlushing(false)
|
||||
|
|
@ -149,7 +150,7 @@ VPXDecoder::DoDecode(MediaRawData* aSample)
|
|||
"WebM image format not I420 or I444");
|
||||
NS_ASSERTION(!alpha_decoded,
|
||||
"Multiple frames per packet that contains alpha");
|
||||
|
||||
|
||||
if (aSample->AlphaSize() > 0) {
|
||||
if(!alpha_decoded){
|
||||
MediaResult rv = DecodeAlpha(&img_alpha, aSample);
|
||||
|
|
@ -221,7 +222,8 @@ VPXDecoder::DoDecode(MediaRawData* aSample)
|
|||
aSample->mKeyframe,
|
||||
aSample->mTimecode,
|
||||
mInfo.ScaledImageRect(img->d_w,
|
||||
img->d_h));
|
||||
img->d_h),
|
||||
mImageAllocator);
|
||||
} else {
|
||||
VideoData::YCbCrBuffer::Plane alpha_plane;
|
||||
alpha_plane.mData = img_alpha->planes[0];
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ private:
|
|||
MediaRawData* aSample);
|
||||
|
||||
const RefPtr<ImageContainer> mImageContainer;
|
||||
RefPtr<layers::KnowsCompositor> mImageAllocator;
|
||||
const RefPtr<TaskQueue> mTaskQueue;
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
Atomic<bool> mIsFlushing;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public:
|
|||
aParams.mTaskQueue,
|
||||
aParams.mCallback,
|
||||
aParams.VideoConfig(),
|
||||
aParams.mKnowsCompositor,
|
||||
aParams.mImageContainer);
|
||||
return decoder.forget();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "MediaInfo.h"
|
||||
#include "VPXDecoder.h"
|
||||
#include "MP4Decoder.h"
|
||||
#include "mozilla/layers/KnowsCompositor.h"
|
||||
|
||||
#include "FFmpegVideoDecoder.h"
|
||||
#include "FFmpegLog.h"
|
||||
|
|
@ -109,8 +110,9 @@ FFmpegVideoDecoder<LIBAV_VER>::PtsCorrectionContext::Reset()
|
|||
FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(FFmpegLibWrapper* aLib,
|
||||
TaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
|
||||
const VideoInfo& aConfig,
|
||||
ImageContainer* aImageContainer)
|
||||
KnowsCompositor* aAllocator, ImageContainer* aImageContainer)
|
||||
: FFmpegDataDecoder(aLib, aTaskQueue, aCallback, GetCodecId(aConfig.mMimeType))
|
||||
, mImageAllocator(aAllocator)
|
||||
, mImageContainer(aImageContainer)
|
||||
, mInfo(aConfig)
|
||||
, mCodecParser(nullptr)
|
||||
|
|
@ -402,7 +404,8 @@ FFmpegVideoDecoder<LIBAV_VER>::CreateImage(int64_t aOffset, int64_t aPts,
|
|||
!!mFrame->key_frame,
|
||||
-1,
|
||||
mInfo.ScaledImageRect(mFrame->width,
|
||||
mFrame->height));
|
||||
mFrame->height),
|
||||
mImageAllocator);
|
||||
|
||||
if (!v) {
|
||||
return MediaResult(NS_ERROR_OUT_OF_MEMORY,
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@ class FFmpegVideoDecoder<LIBAV_VER> : public FFmpegDataDecoder<LIBAV_VER>
|
|||
{
|
||||
typedef mozilla::layers::Image Image;
|
||||
typedef mozilla::layers::ImageContainer ImageContainer;
|
||||
typedef mozilla::layers::KnowsCompositor KnowsCompositor;
|
||||
|
||||
public:
|
||||
FFmpegVideoDecoder(FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue,
|
||||
MediaDataDecoderCallback* aCallback,
|
||||
const VideoInfo& aConfig,
|
||||
KnowsCompositor* aAllocator,
|
||||
ImageContainer* aImageContainer);
|
||||
virtual ~FFmpegVideoDecoder();
|
||||
|
||||
|
|
@ -62,6 +64,7 @@ private:
|
|||
int AllocateYUV420PVideoBuffer(AVCodecContext* aCodecContext,
|
||||
AVFrame* aFrame);
|
||||
|
||||
RefPtr<KnowsCompositor> mImageAllocator;
|
||||
RefPtr<ImageContainer> mImageContainer;
|
||||
VideoInfo mInfo;
|
||||
|
||||
|
|
|
|||
|
|
@ -53,29 +53,41 @@ LoadedScript::LoadedScript(ScriptKind aKind,
|
|||
LoadedScript::~LoadedScript() { DropJSObjects(this); }
|
||||
|
||||
void LoadedScript::AssociateWithScript(JSScript* aScript) {
|
||||
// Set a JSScript's private value to point to this object and
|
||||
// increment our reference count. This is decremented by
|
||||
// HostFinalizeTopLevelScript() below when the JSScript dies.
|
||||
// Set a JSScript's private value to point to this object. The JS engine will
|
||||
// increment our reference count by calling HostAddRefTopLevelScript(). This
|
||||
// is decremented by HostReleaseTopLevelScript() below when the JSScript dies.
|
||||
|
||||
MOZ_ASSERT(JS::GetScriptPrivate(aScript).isUndefined());
|
||||
JS::SetScriptPrivate(aScript, JS::PrivateValue(this));
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void HostFinalizeTopLevelScript(JSFreeOp* aFop, const JS::Value& aPrivate) {
|
||||
// Decrement the reference count of a LoadedScript object that is
|
||||
// pointed to by a dying JSScript. The reference count was
|
||||
// originally incremented by AssociateWithScript() above.
|
||||
|
||||
auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
|
||||
|
||||
inline void CheckModuleScriptPrivate(LoadedScript* script,
|
||||
const JS::Value& aPrivate) {
|
||||
#ifdef DEBUG
|
||||
if (script->IsModuleScript()) {
|
||||
JSObject* module = script->AsModuleScript()->mModuleRecord.unbarrieredGet();
|
||||
MOZ_ASSERT_IF(module, JS::GetModulePrivate(module) == aPrivate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void HostAddRefTopLevelScript(const JS::Value& aPrivate) {
|
||||
// Increment the reference count of a LoadedScript object that is now pointed
|
||||
// to by a JSScript. The reference count is decremented by
|
||||
// HostReleaseTopLevelScript() below.
|
||||
|
||||
auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
|
||||
CheckModuleScriptPrivate(script, aPrivate);
|
||||
script->AddRef();
|
||||
}
|
||||
|
||||
void HostReleaseTopLevelScript(const JS::Value& aPrivate) {
|
||||
// Decrement the reference count of a LoadedScript object that was pointed to
|
||||
// by a JSScript. The reference count was originally incremented by
|
||||
// HostAddRefTopLevelScript() above.
|
||||
|
||||
auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
|
||||
CheckModuleScriptPrivate(script, aPrivate);
|
||||
script->Release();
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +144,6 @@ ModuleScript::UnlinkModuleRecord()
|
|||
this);
|
||||
JS::SetModulePrivate(mModuleRecord, JS::UndefinedValue());
|
||||
mModuleRecord = nullptr;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,13 +162,13 @@ ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord)
|
|||
|
||||
mModuleRecord = aModuleRecord;
|
||||
|
||||
// Make module's host defined field point to this object and
|
||||
// increment our reference count. This is decremented by
|
||||
// UnlinkModuleRecord() above.
|
||||
// Make module's host defined field point to this object. The JS engine will
|
||||
// increment our reference count by calling HostAddRefTopLevelScript(). This
|
||||
// is decremented when the field is cleared in UnlinkModuleRecord() above or
|
||||
// when the module record dies.
|
||||
MOZ_ASSERT(JS::GetModulePrivate(mModuleRecord).isUndefined());
|
||||
JS::SetModulePrivate(mModuleRecord, JS::PrivateValue(this));
|
||||
HoldJSObjects(this);
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ namespace dom {
|
|||
|
||||
class ScriptLoader;
|
||||
|
||||
void HostFinalizeTopLevelScript(JSFreeOp* aFop, const JS::Value& aPrivate);
|
||||
void HostAddRefTopLevelScript(const JS::Value& aPrivate);
|
||||
void HostReleaseTopLevelScript(const JS::Value& aPrivate);
|
||||
|
||||
class ClassicScript;
|
||||
class ModuleScript;
|
||||
|
|
@ -63,7 +64,6 @@ class ClassicScript final : public LoadedScript
|
|||
|
||||
class ModuleScript final : public LoadedScript
|
||||
{
|
||||
JS::Heap<JSObject*> mModuleRecord;
|
||||
JS::Heap<JS::Value> mParseError;
|
||||
JS::Heap<JS::Value> mErrorToRethrow;
|
||||
|
||||
|
|
@ -74,6 +74,8 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ModuleScript,
|
||||
LoadedScript)
|
||||
|
||||
JS::Heap<JSObject*> mModuleRecord;
|
||||
|
||||
ModuleScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
|
||||
|
||||
void SetModuleRecord(JS::Handle<JSObject*> aModuleRecord);
|
||||
|
|
@ -89,7 +91,7 @@ public:
|
|||
|
||||
void UnlinkModuleRecord();
|
||||
|
||||
friend void HostFinalizeTopLevelScript(JSFreeOp*, const JS::Value&);
|
||||
friend void CheckModuleScriptPrivate(LoadedScript*, const JS::Value&);
|
||||
};
|
||||
|
||||
ClassicScript* LoadedScript::AsClassicScript() {
|
||||
|
|
|
|||
|
|
@ -185,7 +185,11 @@ ScriptLoadRequest::MaybeCancelOffThreadScript()
|
|||
}
|
||||
|
||||
JSContext* cx = danger::GetJSContext();
|
||||
JS::CancelOffThreadScript(cx, mOffThreadToken);
|
||||
if (IsModuleRequest()) {
|
||||
JS::CancelOffThreadModule(cx, mOffThreadToken);
|
||||
} else {
|
||||
JS::CancelOffThreadScript(cx, mOffThreadToken);
|
||||
}
|
||||
mOffThreadToken = nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -1109,8 +1113,9 @@ void ScriptLoader::EnsureModuleHooksInitialized() {
|
|||
|
||||
JS::SetModuleResolveHook(rt, HostResolveImportedModule);
|
||||
JS::SetModuleMetadataHook(jsapi.cx(), HostPopulateImportMeta);
|
||||
JS::SetScriptPrivateFinalizeHook(jsapi.cx(), HostFinalizeTopLevelScript);
|
||||
|
||||
JS::SetScriptPrivateReferenceHooks(jsapi.cx(), HostAddRefTopLevelScript,
|
||||
HostReleaseTopLevelScript);
|
||||
|
||||
Preferences::RegisterCallbackAndCall(DynamicImportPrefChangedCallback,
|
||||
"javascript.options.dynamicImport",
|
||||
(void*)nullptr);
|
||||
|
|
@ -2648,7 +2653,7 @@ ScriptLoader::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
|
|||
// Process our request and/or any pending ones
|
||||
ProcessPendingRequests();
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
@ -2758,6 +2763,9 @@ ScriptLoader::HandleLoadError(ScriptLoadRequest *aRequest, nsresult aResult) {
|
|||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req = mDynamicImportRequests.Steal(aRequest);
|
||||
modReq->Cancel();
|
||||
// FinishDynamicImport must happen exactly once for each dynamic import
|
||||
// request. If the load is aborted we do it when we remove the request
|
||||
// from mDynamicImportRequests.
|
||||
FinishDynamicImport(modReq, aResult);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2979,8 +2987,12 @@ ScriptLoader::ParsingComplete(bool aTerminated)
|
|||
for (ScriptLoadRequest* req = mDynamicImportRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
req->Cancel();
|
||||
// FinishDynamicImport must happen exactly once for each dynamic import
|
||||
// request. If the load is aborted we do it when we remove the request
|
||||
// from mDynamicImportRequests.
|
||||
FinishDynamicImport(req->AsModuleRequest(), NS_ERROR_ABORT);
|
||||
}
|
||||
mDynamicImportRequests.Clear();
|
||||
|
||||
if (mParserBlockingRequest) {
|
||||
mParserBlockingRequest->Cancel();
|
||||
|
|
|
|||
|
|
@ -426,17 +426,6 @@ SVGUseElement::LookupHref()
|
|||
nsCOMPtr<nsIURI> targetURI;
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href,
|
||||
GetComposedDoc(), baseURI);
|
||||
|
||||
// Do not allow 'data:' schemes in <use> elements.
|
||||
// See spec update: https://github.com/w3c/svgwg/pull/901
|
||||
if (targetURI) {
|
||||
bool isData;
|
||||
mozilla::Unused << targetURI->SchemeIs("data", &isData);
|
||||
if (isData) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mSource.Reset(this, targetURI);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue