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(
const nsCursor& aCursor, const bool& aHasCustomCursor,
Maybe<BigBuffer>&& aCursorData, const uint32_t& aWidth,
const uint32_t& aHeight, const float& aResolutionX,
const float& aResolutionY, const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat, const uint32_t& aHotspotX,
const uint32_t& aHotspotY, const bool& aForce) {
const nsCursor& aCursor, Maybe<IPCImage>&& aCustomCursor,
const float& aResolutionX, const float& aResolutionY,
const uint32_t& aHotspotX, const uint32_t& aHotspotY, const bool& aForce) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
@ -2335,38 +2332,21 @@ mozilla::ipc::IPCResult BrowserParent::RecvSetCursor(
widget->ClearCachedCursor();
}
nsCOMPtr<imgIContainer> cursorImage;
if (aHasCustomCursor) {
const bool cursorDataValid = [&] {
if (!aCursorData) {
return false;
}
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) {
nsCOMPtr<imgIContainer> customCursorImage;
if (aCustomCursor) {
RefPtr<gfx::DataSourceSurface> customCursorSurface =
nsContentUtils::IPCImageToSurface(*aCustomCursor);
if (!customCursorSurface) {
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);
cursorImage = image::ImageOps::CreateFromDrawable(drawable);
RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(
customCursorSurface, customCursorSurface->GetSize());
customCursorImage = image::ImageOps::CreateFromDrawable(drawable);
}
mCursor = nsIWidget::Cursor{aCursor,
std::move(cursorImage),
std::move(customCursorImage),
aHotspotX,
aHotspotY,
{aResolutionX, aResolutionY}};

View file

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

View file

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

View file

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