/* 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/. */ #ifndef GFXMESSAGEUTILS_H_ #define GFXMESSAGEUTILS_H_ #include #include "DriverCrashGuard.h" #include "FilterSupport.h" #include "ImageTypes.h" #include "RegionBuilder.h" #include "SharedFontList.h" #include "chrome/common/ipc_message_utils.h" #include "gfxFallback.h" #include "gfxFeature.h" #include "gfxPoint.h" #include "gfxRect.h" #include "gfxSparseBitSet.h" #include "gfxTelemetry.h" #include "gfxTypes.h" #include "ipc/EnumSerializer.h" #include "ipc/IPCMessageUtilsSpecializations.h" #include "mozilla/EnumTypeTraits.h" #include "mozilla/gfx/CrossProcessPaint.h" #include "mozilla/gfx/FileHandleWrapper.h" #include "mozilla/gfx/Matrix.h" #include "mozilla/gfx/ScaleFactor.h" #include "mozilla/gfx/ScaleFactors2D.h" #include "mozilla/ipc/FileDescriptor.h" #include "mozilla/ipc/ProtocolMessageUtils.h" #include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/ipc/ShmemMessageUtils.h" #include "nsRect.h" #include "nsRegion.h" #ifdef _MSC_VER # pragma warning(disable : 4800) #endif namespace mozilla { typedef gfxImageFormat PixelFormat; } // namespace mozilla namespace IPC { DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::Matrix, _11, _12, _21, _22, _31, _32); template struct ParamTraits> : ParamTraits_TiedFields< mozilla::gfx::Matrix4x4Typed> {}; DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::Matrix5x4, _11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42, _43, _44, _51, _52, _53, _54); DEFINE_IPC_SERIALIZER_WITH_FIELDS(gfxPoint, x.value, y.value); DEFINE_IPC_SERIALIZER_WITH_FIELDS(gfxSize, width, height); template <> struct ParamTraits { typedef gfxRect paramType; static void Write(MessageWriter* aWriter, const paramType& aParam) { WriteParam(aWriter, aParam.X()); WriteParam(aWriter, aParam.Y()); WriteParam(aWriter, aParam.Width()); WriteParam(aWriter, aParam.Height()); } static bool Read(MessageReader* aReader, paramType* aResult) { auto x = aResult->X(); auto y = aResult->Y(); auto w = aResult->Width(); auto h = aResult->Height(); bool retVal = (ReadParam(aReader, &x) && ReadParam(aReader, &y) && ReadParam(aReader, &w) && ReadParam(aReader, &h)); aResult->SetRect(x, y, w, h); return retVal; } }; template <> struct ParamTraits : public ContiguousEnumSerializer { }; struct gfxContentTypeValidator { using IntegralType = std::underlying_type_t; static bool IsLegalValue(const IntegralType e) { return e == IntegralType(gfxContentType::COLOR) || e == IntegralType(gfxContentType::ALPHA) || e == IntegralType(gfxContentType::COLOR_ALPHA); } }; template <> struct ParamTraits : EnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializer { }; template <> struct ParamTraits : public ContiguousEnumSerializer { }; template <> struct ParamTraits : public ContiguousEnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializer< mozilla::gfx::Fallback, mozilla::gfx::Fallback::NO_CONSTANT_BUFFER_OFFSETTING, mozilla::gfx::Fallback::NumValues> {}; template <> struct ParamTraits : public ContiguousEnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializer {}; template using GfxEnumSerializer = ContiguousEnumSerializerInclusive::min, mozilla::ContiguousEnumValues::max>; template <> struct ParamTraits : public GfxEnumSerializer {}; template <> struct ParamTraits : public GfxEnumSerializer {}; template <> struct ParamTraits : public GfxEnumSerializer {}; template <> struct ParamTraits : public GfxEnumSerializer {}; template <> struct ParamTraits : public GfxEnumSerializer {}; template <> struct ParamTraits : public GfxEnumSerializer {}; template <> struct ParamTraits : public GfxEnumSerializer {}; template <> struct ParamTraits : public GfxEnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializer {}; DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::sRGBColor, r, g, b, a); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::DeviceColor, r, g, b, a); DEFINE_IPC_SERIALIZER_WITH_FIELDS(nsPoint, x, y); DEFINE_IPC_SERIALIZER_WITH_FIELDS(nsIntPoint, x, y); template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct RegionParamTraits { typedef Region paramType; static void Write(MessageWriter* writer, const paramType& param) { for (auto iter = param.RectIter(); !iter.Done(); iter.Next()) { const Rect& r = iter.Get(); MOZ_RELEASE_ASSERT(!r.IsEmpty(), "GFX: rect is empty."); WriteParam(writer, r); } // empty rects are sentinel values because nsRegions will never // contain them WriteParam(writer, Rect()); } static bool Read(MessageReader* reader, paramType* result) { RegionBuilder builder; Rect rect; while (ReadParam(reader, &rect)) { if (rect.IsEmpty()) { *result = builder.ToRegion(); return true; } builder.OrWith(rect); } return false; } }; template struct ParamTraits> : RegionParamTraits< mozilla::gfx::IntRegionTyped, mozilla::gfx::IntRectTyped, typename mozilla::gfx::IntRegionTyped::RectIterator> {}; DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::IntSize, width, height); template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> { typedef mozilla::gfx::RectTyped paramType; static void Write(MessageWriter* writer, const paramType& param) { WriteParam(writer, param.X()); WriteParam(writer, param.Y()); WriteParam(writer, param.Width()); WriteParam(writer, param.Height()); } static bool Read(MessageReader* reader, paramType* result) { auto x = result->X(); auto y = result->Y(); auto w = result->Width(); auto h = result->Height(); bool retVal = (ReadParam(reader, &x) && ReadParam(reader, &y) && ReadParam(reader, &w) && ReadParam(reader, &h)); result->SetRect(x, y, w, h); return retVal; } }; template struct ParamTraits> { typedef mozilla::gfx::RectAbsoluteTyped paramType; static void Write(MessageWriter* writer, const paramType& param) { WriteParam(writer, param.Left()); WriteParam(writer, param.Top()); WriteParam(writer, param.Right()); WriteParam(writer, param.Bottom()); } static bool Read(MessageReader* reader, paramType* result) { auto l = result->Left(); auto t = result->Top(); auto r = result->Right(); auto b = result->Bottom(); bool retVal = (ReadParam(reader, &l) && ReadParam(reader, &t) && ReadParam(reader, &r) && ReadParam(reader, &b)); result->SetBox(l, t, r, b); return retVal; } }; template struct ParamTraits> { typedef mozilla::gfx::IntRectTyped paramType; static void Write(MessageWriter* writer, const paramType& param) { WriteParam(writer, param.X()); WriteParam(writer, param.Y()); WriteParam(writer, param.Width()); WriteParam(writer, param.Height()); } static bool Read(MessageReader* reader, paramType* result) { auto x = result->X(); auto y = result->Y(); auto w = result->Width(); auto h = result->Height(); bool retVal = (ReadParam(reader, &x) && ReadParam(reader, &y) && ReadParam(reader, &w) && ReadParam(reader, &h)); result->SetRect(x, y, w, h); return retVal; } }; DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::RectCornerRadii, radii); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::RoundedRect, rect, corners); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::Margin, top, right, bottom, left); template struct ParamTraits> : ParamTraits_TiedFields> {}; template struct ParamTraits> : ParamTraits_TiedFields> {}; template <> struct ParamTraits { typedef nsRect paramType; static void Write(MessageWriter* writer, const paramType& param) { WriteParam(writer, param.X()); WriteParam(writer, param.Y()); WriteParam(writer, param.Width()); WriteParam(writer, param.Height()); } static bool Read(MessageReader* reader, paramType* result) { auto x = result->X(); auto y = result->Y(); auto w = result->Width(); auto h = result->Height(); bool retVal = (ReadParam(reader, &x) && ReadParam(reader, &y) && ReadParam(reader, &w) && ReadParam(reader, &h)); result->SetRect(x, y, w, h); return retVal; } }; template <> struct ParamTraits : RegionParamTraits {}; struct GeckoProcessTypeValidator { using IntegralType = std::underlying_type_t; static bool IsLegalValue(const IntegralType e) { #define GECKO_PROCESS_TYPE(enum_value, enum_name, string_name, proc_typename, \ process_bin_type, procinfo_typename, \ webidl_typename, allcaps_name) \ if (e == IntegralType(GeckoProcessType::GeckoProcessType_##enum_name)) { \ return true; \ } #include "mozilla/GeckoProcessTypes.h" #undef GECKO_PROCESS_TYPE return false; } }; template <> struct ParamTraits : EnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::ColorDepth, mozilla::gfx::ColorDepth::_First, mozilla::gfx::ColorDepth::_Last> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::TransferFunction, mozilla::gfx::TransferFunction::_First, mozilla::gfx::TransferFunction::_Last> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::ColorRange, mozilla::gfx::ColorRange::_First, mozilla::gfx::ColorRange::_Last> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::YUVColorSpace, mozilla::gfx::YUVColorSpace::_First, mozilla::gfx::YUVColorSpace::_Last> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::YUVRangedColorSpace, mozilla::gfx::YUVRangedColorSpace::_First, mozilla::gfx::YUVRangedColorSpace::_Last> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::ColorSpace2, mozilla::gfx::ColorSpace2::_First, mozilla::gfx::ColorSpace2::_Last> {}; DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::Chromaticity, x, y); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::Smpte2086Metadata, displayPrimaryRed, displayPrimaryGreen, displayPrimaryBlue, whitePoint, maxLuminance, minLuminance); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::ContentLightLevel, maxContentLightLevel, maxFrameAverageLightLevel); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::HDRMetadata, mSmpte2086, mContentLightLevel); template <> struct ParamTraits : public ContiguousEnumSerializer {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::ChromaSubsampling, mozilla::gfx::ChromaSubsampling::_First, mozilla::gfx::ChromaSubsampling::_Last> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::DeviceResetReason, mozilla::gfx::DeviceResetReason::_First, mozilla::gfx::DeviceResetReason::_Last> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< mozilla::gfx::DeviceResetDetectPlace, mozilla::gfx::DeviceResetDetectPlace::_First, mozilla::gfx::DeviceResetDetectPlace::_Last> {}; template <> struct ParamTraits : public ParamTraits> { typedef mozilla::gfx::ImplicitlyCopyableFloatArray paramType; }; DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::gfx::EmptyAttributes); DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::gfx::MergeAttributes); DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::gfx::ToAlphaAttributes); DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::gfx::TileAttributes); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::BlendAttributes, mBlendMode); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::MorphologyAttributes, mOperator, mRadii); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::FloodAttributes, mColor); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::OpacityAttributes, mOpacity); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::OffsetAttributes, mValue); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::DisplacementMapAttributes, mScale, mXChannel, mYChannel); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::TurbulenceAttributes, mOffset, mBaseFrequency, mSeed, mOctaves, mStitchable, mType); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::ImageAttributes, mFilter, mInputIndex, mTransform); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::GaussianBlurAttributes, mStdDeviation); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::DropShadowAttributes, mStdDeviation, mOffset, mColor); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::ColorMatrixAttributes, mType, mValues); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::ComponentTransferAttributes, mTypes, mValues); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::ConvolveMatrixAttributes, mKernelSize, mKernelMatrix, mDivisor, mBias, mTarget, mEdgeMode, mKernelUnitLength, mPreserveAlpha); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::DiffuseLightingAttributes, mLightType, mLightValues, mSurfaceScale, mKernelUnitLength, mColor, mLightingConstant, mSpecularExponent); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::SpecularLightingAttributes, mLightType, mLightValues, mSurfaceScale, mKernelUnitLength, mColor, mLightingConstant, mSpecularExponent); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::CompositeAttributes, mOperator, mCoefficients); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::gfx::Glyph, mIndex, mPosition); template <> struct ParamTraits : public BitFlagsEnumSerializer {}; DEFINE_IPC_SERIALIZER_WITH_FIELDS(gfxSparseBitSet, mBlockIndex, mBlocks); DEFINE_IPC_SERIALIZER_WITH_FIELDS(gfxSparseBitSet::BlockIndex, mIndex); template <> struct ParamTraits { typedef gfxSparseBitSet::Block paramType; static void Write(MessageWriter* aWriter, const paramType& aParam) { aWriter->WriteBytes(&aParam, sizeof(aParam)); } static bool Read(MessageReader* aReader, paramType* aResult) { return aReader->ReadBytesInto(aResult, sizeof(*aResult)); } }; // The actual FontVisibility enum is defined in gfxTypes.h template <> struct ParamTraits : public ContiguousEnumSerializer {}; template <> struct ParamTraits : public BitFlagsEnumSerializer { }; template <> struct ParamTraits { typedef mozilla::gfx::PaintFragment paramType; static void Write(IPC::MessageWriter* aWriter, paramType&& aParam) { if (!aWriter->GetActor()) { aWriter->FatalError("Need an actor"); return; } mozilla::ipc::Shmem shmem; if (aParam.mSize.IsEmpty() || !aWriter->GetActor()->AllocShmem(aParam.mRecording.mLen, &shmem)) { WriteParam(aWriter, mozilla::gfx::IntSize(0, 0)); return; } memcpy(shmem.get(), aParam.mRecording.mData, aParam.mRecording.mLen); WriteParam(aWriter, aParam.mSize); WriteParam(aWriter, std::move(shmem)); WriteParam(aWriter, aParam.mDependencies); } static bool Read(IPC::MessageReader* aReader, paramType* aResult) { if (!aReader->GetActor()) { return false; } if (!ReadParam(aReader, &aResult->mSize)) { return false; } if (aResult->mSize.IsEmpty()) { return true; } mozilla::ipc::Shmem shmem; if (!ReadParam(aReader, &shmem) || !ReadParam(aReader, &aResult->mDependencies)) { aReader->GetActor()->DeallocShmem(shmem); return false; } if (!aResult->mRecording.Allocate(shmem.Size())) { aResult->mSize.SizeTo(0, 0); aReader->GetActor()->DeallocShmem(shmem); return true; } memcpy(aResult->mRecording.mData, shmem.get(), shmem.Size()); aReader->GetActor()->DeallocShmem(shmem); return true; } }; template <> struct ParamTraits { static void Write(MessageWriter* aWriter, mozilla::gfx::FileHandleWrapper* aParam) { if (!aParam) { WriteParam(aWriter, false); return; } WriteParam(aWriter, true); mozilla::ipc::FileDescriptor desc(aParam->GetHandle()); WriteParam(aWriter, desc); } static bool Read(MessageReader* aReader, RefPtr* aResult) { *aResult = nullptr; bool notnull = false; if (!ReadParam(aReader, ¬null)) { return false; } if (!notnull) { return true; } mozilla::ipc::FileDescriptor desc; if (!ReadParam(aReader, &desc)) { return false; } auto wrapper = mozilla::MakeRefPtr( desc.TakePlatformHandle()); *aResult = std::move(wrapper); return true; } }; } // namespace IPC #endif /* GFXMESSAGEUTILS_H_ */