[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[WebKit-https.git] / Source / WebKit / Shared / win / ShareableBitmapDirect2D.cpp
1 /*
2  * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
3  * Copyright (C) 2011 Brent Fulgham <bfulgham@webkit.org>
4  * Copyright (C) 2011 Igalia S.L.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "ShareableBitmap.h"
30
31 #include <WebCore/BitmapImage.h>
32 #include <WebCore/DIBPixelData.h>
33 #include <WebCore/Direct2DOperations.h>
34 #include <WebCore/Direct2DUtilities.h>
35 #include <WebCore/GraphicsContextImplDirect2D.h>
36 #include <WebCore/NotImplemented.h>
37 #include <WebCore/PlatformContextDirect2D.h>
38 #include <wincodec.h>
39 #include <wtf/ProcessID.h>
40
41
42 namespace WebKit {
43 using namespace WebCore;
44
45 static const auto bitmapFormat = GUID_WICPixelFormat32bppPBGRA;
46
47 static unsigned strideForWidth(unsigned width)
48 {
49     static unsigned bitsPerPixel = Direct2D::bitsPerPixel(bitmapFormat);
50     return bitsPerPixel * width / 8;
51 }
52
53 Checked<unsigned, RecordOverflow> ShareableBitmap::calculateBytesPerRow(WebCore::IntSize size, const Configuration& configuration)
54 {
55     return calculateBytesPerPixel(configuration) * size.width();
56 }
57
58 unsigned ShareableBitmap::calculateBytesPerPixel(const Configuration&)
59 {
60     return 4;
61 }
62
63 static inline COMPtr<IWICBitmap> createSurfaceFromData(void* data, const WebCore::IntSize& size)
64 {
65     const unsigned stride = strideForWidth(size.width());
66     return Direct2D::createDirect2DImageSurfaceWithData(data, size, stride);
67 }
68
69 std::unique_ptr<GraphicsContext> ShareableBitmap::createGraphicsContext()
70 {
71     m_bitmap = createDirect2DSurface();
72     COMPtr<ID2D1RenderTarget> bitmapContext = Direct2D::createRenderTargetFromWICBitmap(m_bitmap.get());
73     return makeUnique<GraphicsContext>(GraphicsContextImplDirect2D::createFactory(bitmapContext.get()));
74 }
75
76 void ShareableBitmap::paint(GraphicsContext& context, const IntPoint& dstPoint, const IntRect& srcRect)
77 {
78     paint(context, 1, dstPoint, srcRect);
79 }
80
81 void ShareableBitmap::paint(GraphicsContext& context, float scaleFactor, const IntPoint& dstPoint, const IntRect& srcRect)
82 {
83     auto surface = createDirect2DSurface();
84
85     FloatRect destRect(dstPoint, srcRect.size());
86     FloatRect srcRectScaled(srcRect);
87     srcRectScaled.scale(scaleFactor);
88
89     ASSERT(context.hasPlatformContext());
90     auto& state = context.state();
91     auto& platformContext = *context.platformContext();
92
93     Direct2D::drawNativeImage(platformContext, surface.get(), m_size, destRect, srcRectScaled, state.compositeOperator, state.blendMode, ImageOrientation(), state.imageInterpolationQuality, state.alpha, Direct2D::ShadowState(state));
94 }
95
96 COMPtr<IWICBitmap> ShareableBitmap::createDirect2DSurface()
97 {
98     m_bitmap = createSurfaceFromData(data(), m_size);
99     return m_bitmap;
100 }
101
102 RefPtr<Image> ShareableBitmap::createImage()
103 {
104     auto surface = createDirect2DSurface();
105     if (!surface)
106         return nullptr;
107
108     return BitmapImage::create(WTFMove(surface));
109 }
110
111 void ShareableBitmap::sync(GraphicsContext& graphicsContext)
112 {
113     ASSERT(m_bitmap);
114
115     graphicsContext.endDraw();
116
117     WICRect rcLock = { 0, 0, m_size.width(), m_size.height() };
118
119     COMPtr<IWICBitmapLock> bitmapDataLock;
120     HRESULT hr = m_bitmap->Lock(&rcLock, WICBitmapLockRead, &bitmapDataLock);
121     if (SUCCEEDED(hr)) {
122         UINT bufferSize = 0;
123         WICInProcPointer dataPtr = nullptr;
124         hr = bitmapDataLock->GetDataPointer(&bufferSize, &dataPtr);
125         if (SUCCEEDED(hr))
126             memcpy(data(), reinterpret_cast<char*>(dataPtr), bufferSize);
127     }
128
129     // Once we are done modifying the data, unlock the bitmap
130     bitmapDataLock = nullptr;
131 }
132
133 } // namespace WebKit