Bug 1892598 - Reuse IPCImage for PBrowser::SetCursor; r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D208075
This commit is contained in:
Edgar Chen 2024-04-23 06:01:47 +00:00
parent 1f5e1875cb
commit c63bf1ce7b
4 changed files with 26 additions and 71 deletions

View file

@ -2320,12 +2320,9 @@ mozilla::ipc::IPCResult BrowserParent::RecvAsyncMessage(
} }
mozilla::ipc::IPCResult BrowserParent::RecvSetCursor( mozilla::ipc::IPCResult BrowserParent::RecvSetCursor(
const nsCursor& aCursor, const bool& aHasCustomCursor, const nsCursor& aCursor, Maybe<IPCImage>&& aCustomCursor,
Maybe<BigBuffer>&& aCursorData, const uint32_t& aWidth, const float& aResolutionX, const float& aResolutionY,
const uint32_t& aHeight, const float& aResolutionX, const uint32_t& aHotspotX, const uint32_t& aHotspotY, const bool& aForce) {
const float& aResolutionY, const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat, const uint32_t& aHotspotX,
const uint32_t& aHotspotY, const bool& aForce) {
nsCOMPtr<nsIWidget> widget = GetWidget(); nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) { if (!widget) {
return IPC_OK(); return IPC_OK();
@ -2335,38 +2332,21 @@ mozilla::ipc::IPCResult BrowserParent::RecvSetCursor(
widget->ClearCachedCursor(); widget->ClearCachedCursor();
} }
nsCOMPtr<imgIContainer> cursorImage; nsCOMPtr<imgIContainer> customCursorImage;
if (aHasCustomCursor) { if (aCustomCursor) {
const bool cursorDataValid = [&] { RefPtr<gfx::DataSourceSurface> customCursorSurface =
if (!aCursorData) { nsContentUtils::IPCImageToSurface(*aCustomCursor);
return false; if (!customCursorSurface) {
}
auto expectedSize = CheckedInt<uint32_t>(aHeight) * aStride;
if (!expectedSize.isValid() ||
expectedSize.value() != aCursorData->Size()) {
return false;
}
auto minStride =
CheckedInt<uint32_t>(aWidth) * gfx::BytesPerPixel(aFormat);
if (!minStride.isValid() || aStride < minStride.value()) {
return false;
}
return true;
}();
if (!cursorDataValid) {
return IPC_FAIL(this, "Invalid custom cursor data"); return IPC_FAIL(this, "Invalid custom cursor data");
} }
const gfx::IntSize size(aWidth, aHeight);
RefPtr<gfx::DataSourceSurface> customCursor =
gfx::CreateDataSourceSurfaceFromData(size, aFormat, aCursorData->Data(),
aStride);
RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(customCursor, size); RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(
cursorImage = image::ImageOps::CreateFromDrawable(drawable); customCursorSurface, customCursorSurface->GetSize());
customCursorImage = image::ImageOps::CreateFromDrawable(drawable);
} }
mCursor = nsIWidget::Cursor{aCursor, mCursor = nsIWidget::Cursor{aCursor,
std::move(cursorImage), std::move(customCursorImage),
aHotspotX, aHotspotX,
aHotspotY, aHotspotY,
{aResolutionX, aResolutionY}}; {aResolutionX, aResolutionY}};

View file

@ -383,12 +383,9 @@ class BrowserParent final : public PBrowserParent,
nsTArray<nsCString>&& aDisabledCommands); nsTArray<nsCString>&& aDisabledCommands);
mozilla::ipc::IPCResult RecvSetCursor( mozilla::ipc::IPCResult RecvSetCursor(
const nsCursor& aValue, const bool& aHasCustomCursor, const nsCursor& aValue, Maybe<IPCImage>&& aCustomCursor,
Maybe<BigBuffer>&& aCursorData, const uint32_t& aWidth, const float& aResolutionX, const float& aResolutionY,
const uint32_t& aHeight, const float& aResolutionX, const uint32_t& aHotspotX, const uint32_t& aHotspotY, const bool& aForce);
const float& aResolutionY, const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat, const uint32_t& aHotspotX,
const uint32_t& aHotspotY, const bool& aForce);
mozilla::ipc::IPCResult RecvSetLinkStatus(const nsString& aStatus); mozilla::ipc::IPCResult RecvSetLinkStatus(const nsString& aStatus);

View file

@ -376,23 +376,12 @@ parent:
* Set the native cursor. * Set the native cursor.
* @param value * @param value
* The widget cursor to set. * The widget cursor to set.
* @param hasCustomCursor * @param customCursor
* Whether there's any custom cursor represented by cursorData and * Serialized image data for custom cursor.
* company.
* @param customCursorData
* Serialized image data.
* @param width
* Width of the image.
* @param height
* Height of the image.
* @param resolutionX * @param resolutionX
* Resolution of the image X axis in dppx units. * Resolution of the image X axis in dppx units.
* @param resolutionY * @param resolutionY
* Resolution of the image Y axis in dppx units. * Resolution of the image Y axis in dppx units.
* @param stride
* Stride used in the image data.
* @param format
* Image format, see gfx::SurfaceFormat for possible values.
* @param hotspotX * @param hotspotX
* Horizontal hotspot of the image, as specified by the css cursor property. * Horizontal hotspot of the image, as specified by the css cursor property.
* @param hotspotY * @param hotspotY
@ -402,11 +391,8 @@ parent:
* update. * update.
*/ */
async SetCursor(nsCursor value, async SetCursor(nsCursor value,
bool hasCustomCursor, IPCImage? customCursor,
BigBuffer? customCursorData,
uint32_t width, uint32_t height,
float resolutionX, float resolutionY, float resolutionX, float resolutionY,
uint32_t stride, SurfaceFormat format,
uint32_t hotspotX, uint32_t hotspotY, bool force); uint32_t hotspotX, uint32_t hotspotY, bool force);
/** /**

View file

@ -900,17 +900,14 @@ void PuppetWidget::SetCursor(const Cursor& aCursor) {
return; return;
} }
bool hasCustomCursor = false;
Maybe<mozilla::ipc::BigBuffer> customCursorData;
size_t length = 0;
IntSize customCursorSize;
int32_t stride = 0;
auto format = SurfaceFormat::B8G8R8A8;
ImageResolution resolution = aCursor.mResolution; ImageResolution resolution = aCursor.mResolution;
Maybe<IPCImage> customCursor;
if (aCursor.IsCustom()) { if (aCursor.IsCustom()) {
int32_t width = 0, height = 0; int32_t width = 0;
int32_t height = 0;
aCursor.mContainer->GetWidth(&width); aCursor.mContainer->GetWidth(&width);
aCursor.mContainer->GetHeight(&height); aCursor.mContainer->GetHeight(&height);
const int32_t flags = const int32_t flags =
imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY; imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY;
RefPtr<SourceSurface> surface; RefPtr<SourceSurface> surface;
@ -928,22 +925,17 @@ void PuppetWidget::SetCursor(const Cursor& aCursor) {
surface = surface =
aCursor.mContainer->GetFrame(imgIContainer::FRAME_CURRENT, flags); aCursor.mContainer->GetFrame(imgIContainer::FRAME_CURRENT, flags);
} }
if (surface) { if (surface) {
if (RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface()) { if (RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface()) {
hasCustomCursor = true; customCursor = nsContentUtils::SurfaceToIPCImage(*dataSurface);
customCursorData =
nsContentUtils::GetSurfaceData(*dataSurface, &length, &stride);
customCursorSize = dataSurface->GetSize();
format = dataSurface->GetFormat();
} }
} }
} }
if (!mBrowserChild->SendSetCursor( if (!mBrowserChild->SendSetCursor(
aCursor.mDefaultCursor, hasCustomCursor, std::move(customCursorData), aCursor.mDefaultCursor, std::move(customCursor), resolution.mX,
customCursorSize.width, customCursorSize.height, resolution.mX, resolution.mY, aCursor.mHotspotX, aCursor.mHotspotY, force)) {
resolution.mY, stride, format, aCursor.mHotspotX, aCursor.mHotspotY,
force)) {
return; return;
} }
mCursor = aCursor; mCursor = aCursor;