Skip to content

Commit

Permalink
Cherry-pick 5870285. rdar://problem/108072383
Browse files Browse the repository at this point in the history
    [GPU Process] (REGRESSION 262607@main): Copy pixels of CGImage only if it is not a sub-image
    https://bugs.webkit.org/show_bug.cgi?id=255677
    rdar://108072383

    Reviewed by Simon Fraser.

    In ShareableBitmap::createFromImagePixels(), CGImage and its CGDataProvider
    may disagree about how many bytes are in the pixels buffers. CGImage is most
    likely a sub-image of another CGImage which inherits its meta data but not
    the full pixels buffer.

    In this case we should fallback to ShareableBitmap::createFromImageDraw().
    Ortherwise  ShareableBitmapConfiguration will falsely describe the data in the
    SharedMemory.

    * Source/WebKit/Shared/cg/ShareableBitmapCG.cpp:
    (WebKit::ShareableBitmap::createFromImagePixels):

    Canonical link: https://commits.webkit.org/264021@main

Identifier: 263769.31@safari-7616.1.14.10-branch
  • Loading branch information
shallawa authored and MyahCobbs committed May 15, 2023
1 parent eca1876 commit 2b611c6
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions Source/WebKit/Shared/cg/ShareableBitmapCG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "config.h"
#include "ShareableBitmap.h"

#include "Logging.h"
#include <WebCore/BitmapImage.h>
#include <WebCore/GraphicsContextCG.h>
#include <WebCore/IOSurface.h>
Expand Down Expand Up @@ -119,17 +120,29 @@ RefPtr<ShareableBitmap> ShareableBitmap::createFromImagePixels(NativeImage& imag
return nullptr;

const auto* bytes = reinterpret_cast<const uint8_t*>(CFDataGetBytePtr(pixels.get()));
auto sizeInBytes = CFDataGetLength(pixels.get());
if (!bytes || !sizeInBytes)
CheckedUint32 sizeInBytes = CFDataGetLength(pixels.get());
if (!bytes || !sizeInBytes || sizeInBytes.hasOverflowed())
return nullptr;

auto configuration = ShareableBitmapConfiguration(image);
if (configuration.sizeInBytes() != sizeInBytes) {
LOG_WITH_STREAM(Images, stream
<< "ShareableBitmap::createFromImagePixels() " << image. platformImage().get()
<< " CGImage size: " << configuration.size()
<< " CGImage bytesPerRow: " << configuration.bytesPerRow()
<< " CGImage sizeInBytes: " << configuration.sizeInBytes()
<< " CGDataProvider sizeInBytes: " << sizeInBytes
<< " CGImage and its CGDataProvider disagree about how many bytes are in pixels buffer. CGImage is a sub-image; bailing.");
return nullptr;
}

RefPtr<SharedMemory> sharedMemory = SharedMemory::allocate(sizeInBytes);
if (!sharedMemory)
return nullptr;

memcpy(sharedMemory->data(), bytes, sizeInBytes);

return adoptRef(new ShareableBitmap(ShareableBitmapConfiguration(image), sharedMemory.releaseNonNull()));
return adoptRef(new ShareableBitmap(configuration, sharedMemory.releaseNonNull()));
}

std::unique_ptr<GraphicsContext> ShareableBitmap::createGraphicsContext()
Expand Down

0 comments on commit 2b611c6

Please sign in to comment.