1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "ShareableBitmap.h"
28
29#include "SharedMemory.h"
30#include "WebCoreArgumentCoders.h"
31#include <WebCore/GraphicsContext.h>
32
33namespace WebKit {
34using namespace WebCore;
35
36ShareableBitmap::Handle::Handle()
37{
38}
39
40void ShareableBitmap::Handle::encode(IPC::Encoder& encoder) const
41{
42 encoder << m_handle;
43 encoder << m_size;
44 encoder << m_configuration;
45}
46
47bool ShareableBitmap::Handle::decode(IPC::Decoder& decoder, Handle& handle)
48{
49 if (!decoder.decode(handle.m_handle))
50 return false;
51 if (!decoder.decode(handle.m_size))
52 return false;
53 if (!decoder.decode(handle.m_configuration))
54 return false;
55 return true;
56}
57
58void ShareableBitmap::Handle::clear()
59{
60 m_handle.clear();
61 m_size = IntSize();
62 m_configuration = { };
63}
64
65void ShareableBitmap::Configuration::encode(IPC::Encoder& encoder) const
66{
67 encoder << isOpaque;
68#if PLATFORM(COCOA)
69 encoder << colorSpace;
70#endif
71}
72
73bool ShareableBitmap::Configuration::decode(IPC::Decoder& decoder, Configuration& configuration)
74{
75 if (!decoder.decode(configuration.isOpaque))
76 return false;
77#if PLATFORM(COCOA)
78 if (!decoder.decode(configuration.colorSpace))
79 return false;
80#endif
81 return true;
82}
83
84RefPtr<ShareableBitmap> ShareableBitmap::create(const IntSize& size, Configuration configuration)
85{
86 auto numBytes = numBytesForSize(size, configuration);
87 if (numBytes.hasOverflowed())
88 return nullptr;
89
90 void* data = 0;
91 if (!tryFastMalloc(numBytes.unsafeGet()).getValue(data))
92 return nullptr;
93
94 return adoptRef(new ShareableBitmap(size, configuration, data));
95}
96
97RefPtr<ShareableBitmap> ShareableBitmap::createShareable(const IntSize& size, Configuration configuration)
98{
99 auto numBytes = numBytesForSize(size, configuration);
100 if (numBytes.hasOverflowed())
101 return nullptr;
102
103 RefPtr<SharedMemory> sharedMemory = SharedMemory::allocate(numBytes.unsafeGet());
104 if (!sharedMemory)
105 return nullptr;
106
107 return adoptRef(new ShareableBitmap(size, configuration, sharedMemory));
108}
109
110RefPtr<ShareableBitmap> ShareableBitmap::create(const IntSize& size, Configuration configuration, RefPtr<SharedMemory> sharedMemory)
111{
112 ASSERT(sharedMemory);
113
114 auto numBytes = numBytesForSize(size, configuration);
115 if (numBytes.hasOverflowed())
116 return nullptr;
117 if (sharedMemory->size() < numBytes.unsafeGet()) {
118 ASSERT_NOT_REACHED();
119 return nullptr;
120 }
121
122 return adoptRef(new ShareableBitmap(size, configuration, sharedMemory));
123}
124
125RefPtr<ShareableBitmap> ShareableBitmap::create(const Handle& handle, SharedMemory::Protection protection)
126{
127 // Create the shared memory.
128 auto sharedMemory = SharedMemory::map(handle.m_handle, protection);
129 if (!sharedMemory)
130 return nullptr;
131
132 return create(handle.m_size, handle.m_configuration, WTFMove(sharedMemory));
133}
134
135bool ShareableBitmap::createHandle(Handle& handle, SharedMemory::Protection protection) const
136{
137 ASSERT(isBackedBySharedMemory());
138
139 if (!m_sharedMemory->createHandle(handle.m_handle, protection))
140 return false;
141 handle.m_size = m_size;
142 handle.m_configuration = m_configuration;
143 return true;
144}
145
146ShareableBitmap::ShareableBitmap(const IntSize& size, Configuration configuration, void* data)
147 : m_size(size)
148 , m_configuration(configuration)
149 , m_data(data)
150{
151}
152
153ShareableBitmap::ShareableBitmap(const IntSize& size, Configuration configuration, RefPtr<SharedMemory> sharedMemory)
154 : m_size(size)
155 , m_configuration(configuration)
156 , m_sharedMemory(sharedMemory)
157 , m_data(nullptr)
158{
159}
160
161ShareableBitmap::~ShareableBitmap()
162{
163 if (!isBackedBySharedMemory())
164 fastFree(m_data);
165}
166
167void* ShareableBitmap::data() const
168{
169 if (isBackedBySharedMemory())
170 return m_sharedMemory->data();
171
172 ASSERT(m_data);
173 return m_data;
174}
175
176Checked<unsigned, RecordOverflow> ShareableBitmap::numBytesForSize(WebCore::IntSize size, const ShareableBitmap::Configuration& configuration)
177{
178 return calculateBytesPerRow(size, configuration) * size.height();
179}
180
181} // namespace WebKit
182