blob: e6b581404f196cac3e4349a91febbd7025d77edd [file] [log] [blame]
/*
* Copyright (C) 2010-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "SharedMemory.h"
#include <WebCore/DestinationColorSpace.h>
#include <WebCore/IntRect.h>
#include <WebCore/PlatformImage.h>
#include <wtf/RefPtr.h>
#include <wtf/ThreadSafeRefCounted.h>
#if USE(DIRECT2D)
interface ID2D1Bitmap;
interface ID2D1RenderTarget;
interface ID3D11Device1;
interface IDXGIKeyedMutex;
interface IDXGISurface1;
#include <WebCore/COMPtr.h>
#endif
namespace WebCore {
class Image;
class GraphicsContext;
}
namespace WebKit {
class ShareableBitmap : public ThreadSafeRefCounted<ShareableBitmap> {
public:
struct Configuration {
std::optional<WebCore::DestinationColorSpace> colorSpace;
bool isOpaque { false };
#if USE(DIRECT2D)
mutable HANDLE sharedResourceHandle { nullptr };
#endif
void encode(IPC::Encoder&) const;
static WARN_UNUSED_RETURN bool decode(IPC::Decoder&, Configuration&);
};
class Handle {
WTF_MAKE_NONCOPYABLE(Handle);
public:
Handle();
Handle(Handle&&) = default;
Handle& operator=(Handle&&) = default;
bool isNull() const { return m_handle.isNull(); }
void clear();
void encode(IPC::Encoder&) const;
static WARN_UNUSED_RETURN bool decode(IPC::Decoder&, Handle&);
private:
friend class ShareableBitmap;
mutable SharedMemory::Handle m_handle;
WebCore::IntSize m_size;
Configuration m_configuration;
};
static void validateConfiguration(Configuration&);
static CheckedUint32 numBytesForSize(WebCore::IntSize, const ShareableBitmap::Configuration&);
static CheckedUint32 calculateBytesPerRow(WebCore::IntSize, const Configuration&);
static CheckedUint32 calculateBytesPerPixel(const Configuration&);
// Create a shareable bitmap that uses malloced memory.
static RefPtr<ShareableBitmap> create(const WebCore::IntSize&, Configuration);
// Create a shareable bitmap whose backing memory can be shared with another process.
static RefPtr<ShareableBitmap> createShareable(const WebCore::IntSize&, Configuration);
// Create a shareable bitmap from an already existing shared memory block.
static RefPtr<ShareableBitmap> create(const WebCore::IntSize&, Configuration, RefPtr<SharedMemory>);
// Create a shareable bitmap from a handle.
static RefPtr<ShareableBitmap> create(const Handle&, SharedMemory::Protection = SharedMemory::Protection::ReadWrite);
// Create a handle.
bool createHandle(Handle&, SharedMemory::Protection = SharedMemory::Protection::ReadWrite) const;
~ShareableBitmap();
const WebCore::IntSize& size() const { return m_size; }
WebCore::IntRect bounds() const { return WebCore::IntRect(WebCore::IntPoint(), size()); }
// Create a graphics context that can be used to paint into the backing store.
std::unique_ptr<WebCore::GraphicsContext> createGraphicsContext();
// Paint the backing store into the given context.
void paint(WebCore::GraphicsContext&, const WebCore::IntPoint& destination, const WebCore::IntRect& source);
void paint(WebCore::GraphicsContext&, float scaleFactor, const WebCore::IntPoint& destination, const WebCore::IntRect& source);
bool isBackedBySharedMemory() const { return m_sharedMemory; }
// This creates a bitmap image that directly references the shared bitmap data.
// This is only safe to use when we know that the contents of the shareable bitmap won't change.
RefPtr<WebCore::Image> createImage();
#if USE(CG)
// This creates a copied CGImageRef (most likely a copy-on-write) of the shareable bitmap.
RetainPtr<CGImageRef> makeCGImageCopy();
// This creates a CGImageRef that directly references the shared bitmap data.
// This is only safe to use when we know that the contents of the shareable bitmap won't change.
RetainPtr<CGImageRef> makeCGImage();
WebCore::PlatformImagePtr createPlatformImage() { return makeCGImageCopy(); }
#elif USE(CAIRO)
// This creates a BitmapImage that directly references the shared bitmap data.
// This is only safe to use when we know that the contents of the shareable bitmap won't change.
RefPtr<cairo_surface_t> createCairoSurface();
WebCore::PlatformImagePtr createPlatformImage() { return createCairoSurface(); }
#elif USE(DIRECT2D)
COMPtr<ID2D1Bitmap> createDirect2DSurface(ID3D11Device1*, ID2D1RenderTarget*);
IDXGISurface1* dxSurface() { return m_surface.get(); }
void createSharedResource();
void disposeSharedResource();
void leakSharedResource();
WebCore::PlatformImagePtr createPlatformImage() { return nullptr; }
#endif
private:
ShareableBitmap(const WebCore::IntSize&, Configuration, void*);
ShareableBitmap(const WebCore::IntSize&, Configuration, RefPtr<SharedMemory>);
#if USE(CG)
RetainPtr<CGImageRef> createCGImage(CGDataProviderRef) const;
static void releaseBitmapContextData(void* typelessBitmap, void* typelessData);
static void releaseDataProviderData(void* typelessBitmap, const void* typelessData, size_t);
#endif
#if USE(CAIRO)
static void releaseSurfaceData(void* typelessBitmap);
#endif
public:
void* data() const;
size_t bytesPerRow() const { return calculateBytesPerRow(m_size, m_configuration); }
private:
size_t sizeInBytes() const { return numBytesForSize(m_size, m_configuration); }
WebCore::IntSize m_size;
Configuration m_configuration;
#if USE(DIRECT2D)
COMPtr<IDXGISurface1> m_surface;
COMPtr<IDXGIKeyedMutex> m_surfaceMutex;
COMPtr<ID2D1Bitmap> m_bitmap;
#endif
#if USE(CG)
bool m_releaseBitmapContextDataCalled { false };
#endif
// If the shareable bitmap is backed by shared memory, this points to the shared memory object.
RefPtr<SharedMemory> m_sharedMemory;
// If the shareable bitmap is backed by fastMalloced memory, this points to the data.
void* m_data { nullptr };
};
} // namespace WebKit