diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 6919a282491c..0e3541c38f2c 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -5501,6 +5501,52 @@ static Matrix ComputeRotationMatrix(gfxFloat aRotatedWidth, .PostTranslate(shiftLeftTopToOrigin); } +// - + +Maybe ValidSurfaceDescriptorForRemoteCanvas2d( + const layers::SurfaceDescriptor& sdConst) { + auto sd = sdConst; // Copy, so we can mutate it. + if (sd.type() != layers::SurfaceDescriptor::TSurfaceDescriptorGPUVideo) { + return Nothing(); + } + + auto& sdv = sd.get_SurfaceDescriptorGPUVideo(); + if (sdv.type() != + layers::SurfaceDescriptorGPUVideo::TSurfaceDescriptorRemoteDecoder) { + return Nothing(); + } + auto& sdrd = sdv.get_SurfaceDescriptorRemoteDecoder(); + auto& subdesc = sdrd.subdesc(); + switch (subdesc.type()) { + case layers::RemoteDecoderVideoSubDescriptor::Tnull_t: + break; +#ifdef XP_MACOSX + case layers::RemoteDecoderVideoSubDescriptor:: + TSurfaceDescriptorMacIOSurface: { + const auto& ssd = subdesc.get_SurfaceDescriptorMacIOSurface(); + if (ssd.gpuFence()) { + return Nothing(); + } + break; + } +#endif +#ifdef XP_WIN + case layers::RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorD3D10: { + if (!StaticPrefs::gfx_canvas_remote_use_draw_image_fast_path_d3d()) { + return Nothing(); + } + auto& ssd = subdesc.get_SurfaceDescriptorD3D10(); + ssd.handle() = + nullptr; // Not IPC-able, but it's just an optimization to have this. + break; + } +#endif + default: + return Nothing(); + } + return Some(sd); +} + static Maybe MaybeGetSurfaceDescriptorForRemoteCanvas( const SurfaceFromElementResult& aResult) { @@ -5512,43 +5558,9 @@ MaybeGetSurfaceDescriptorForRemoteCanvas( return Nothing(); } - Maybe sd; - sd = aResult.mLayersImage->GetDesc(); - if (sd.isNothing() || - sd.ref().type() != - layers::SurfaceDescriptor::TSurfaceDescriptorGPUVideo) { - return Nothing(); - } - - auto& sdv = sd.ref().get_SurfaceDescriptorGPUVideo(); - const auto& sdvType = sdv.type(); - if (sdvType == - layers::SurfaceDescriptorGPUVideo::TSurfaceDescriptorRemoteDecoder) { - auto& sdrd = sdv.get_SurfaceDescriptorRemoteDecoder(); - auto& subdesc = sdrd.subdesc(); - const auto& subdescType = subdesc.type(); - if (subdescType == layers::RemoteDecoderVideoSubDescriptor::Tnull_t) { - return sd; - } - if (subdescType == layers::RemoteDecoderVideoSubDescriptor:: - TSurfaceDescriptorMacIOSurface) { - return sd; - } - if (subdescType == - layers::RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorD3D10 && - StaticPrefs::gfx_canvas_remote_use_draw_image_fast_path_d3d()) { - auto& descD3D10 = subdesc.get_SurfaceDescriptorD3D10(); - // Clear FileHandleWrapper, since FileHandleWrapper::mHandle could not be - // cross process delivered by using Shmem. Cross-process delivery of - // FileHandleWrapper::mHandle is not possible simply by using shmen. When - // it is tried, parent side process just causes crash during destroying - // FileHandleWrapper. - descD3D10.handle() = nullptr; - return sd; - } - } - - return Nothing(); + const auto sd = aResult.mLayersImage->GetDesc(); + if (!sd) return Nothing(); + return ValidSurfaceDescriptorForRemoteCanvas2d(*sd); } // drawImage(in HTMLImageElement image, in float dx, in float dy); diff --git a/dom/canvas/CanvasRenderingContextHelper.h b/dom/canvas/CanvasRenderingContextHelper.h index 77146d2431a2..68c1212c76ed 100644 --- a/dom/canvas/CanvasRenderingContextHelper.h +++ b/dom/canvas/CanvasRenderingContextHelper.h @@ -19,6 +19,10 @@ namespace mozilla { class ErrorResult; +namespace layers { +class SurfaceDescriptor; +} // namespace layers + namespace dom { class BlobCallback; @@ -89,6 +93,9 @@ class CanvasRenderingContextHelper { nsCOMPtr mCurrentContext; }; +Maybe ValidSurfaceDescriptorForRemoteCanvas2d( + const layers::SurfaceDescriptor&); + } // namespace dom namespace CanvasUtils { bool GetCanvasContextType(const nsAString&, dom::CanvasContextType* const); diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h index 8c898089bdf4..032edcc85410 100644 --- a/gfx/2d/RecordedEventImpl.h +++ b/gfx/2d/RecordedEventImpl.h @@ -17,6 +17,9 @@ #include "ScaledFontBase.h" #include "SFNTData.h" +#include "mozilla/dom/CanvasRenderingContextHelper.h" +#include "mozilla/IntegerRange.h" +#include "mozilla/layers/BuildConstants.h" #include "mozilla/layers/LayersSurfaces.h" namespace mozilla { @@ -3247,6 +3250,35 @@ inline bool RecordedDrawSurfaceDescriptor::PlayEvent( return true; } +template +struct ElementStreamFormat { + using T = layers::SurfaceDescriptor; + + static void Write(S& s, const T& t) { + // More rigorous version is coming soon! -Kelsey + const auto valid = dom::ValidSurfaceDescriptorForRemoteCanvas2d(t); + MOZ_RELEASE_ASSERT(valid && *valid == t); + if (kIsDebug) { + // We better be able to memcpy and destroy this if we're going to send it + // over IPC! + constexpr int A_COUPLE_TIMES = 3; + for (const auto i : IntegerRange(A_COUPLE_TIMES)) { + (void)i; + auto copy = T{}; + memcpy(©, &t, sizeof(T)); + } + } + const auto& tValid = *valid; + s.write(reinterpret_cast(&tValid), sizeof(T)); + } + static void Read(S& s, T& t) { + s.read(reinterpret_cast(&t), sizeof(T)); + const auto valid = dom::ValidSurfaceDescriptorForRemoteCanvas2d(t); + MOZ_RELEASE_ASSERT(valid && *valid == t); + t = *valid; + } +}; + template void RecordedDrawSurfaceDescriptor::Record(S& aStream) const { WriteElement(aStream, mDesc); diff --git a/gfx/2d/RecordingTypes.h b/gfx/2d/RecordingTypes.h index fa7f0153e2ed..d80f7e6b4be0 100644 --- a/gfx/2d/RecordingTypes.h +++ b/gfx/2d/RecordingTypes.h @@ -7,7 +7,7 @@ #ifndef MOZILLA_GFX_RECORDINGTYPES_H_ #define MOZILLA_GFX_RECORDINGTYPES_H_ -#include +#include #include #include "Logging.h" @@ -18,12 +18,15 @@ namespace gfx { template struct ElementStreamFormat { static void Write(S& aStream, const T& aElement) { + static_assert(std::is_trivially_copyable_v); aStream.write(reinterpret_cast(&aElement), sizeof(T)); } static void Read(S& aStream, T& aElement) { + static_assert(std::is_trivially_copyable_v); aStream.read(reinterpret_cast(&aElement), sizeof(T)); } }; + template struct ElementStreamFormat { static void Write(S& aStream, const bool& aElement) { diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index fcc81a61971b..c08fe2cb20b4 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -1960,7 +1960,7 @@ inline auto MaybeFind(C& container, const K& key) std::shared_ptr GLBlitHelper::GetColorLutTex( const ColorLutKey& request) const { - if (const auto found = MaybeFind(mColorLutTexMap, request)) { + if (const auto found = gl::MaybeFind(mColorLutTexMap, request)) { return *found; // Might be *Some(nullptr) -> nullptr! }