2 * Copyright 2014 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/port.h"
22 #include "d2d1_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(d2d
);
26 static inline struct d2d_bitmap
*impl_from_ID2D1Bitmap(ID2D1Bitmap
*iface
)
28 return CONTAINING_RECORD(iface
, struct d2d_bitmap
, ID2D1Bitmap_iface
);
31 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_QueryInterface(ID2D1Bitmap
*iface
, REFIID iid
, void **out
)
33 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
35 if (IsEqualGUID(iid
, &IID_ID2D1Bitmap
)
36 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
37 || IsEqualGUID(iid
, &IID_IUnknown
))
39 ID2D1Bitmap_AddRef(iface
);
44 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
50 static ULONG STDMETHODCALLTYPE
d2d_bitmap_AddRef(ID2D1Bitmap
*iface
)
52 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap(iface
);
53 ULONG refcount
= InterlockedIncrement(&bitmap
->refcount
);
55 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
60 static ULONG STDMETHODCALLTYPE
d2d_bitmap_Release(ID2D1Bitmap
*iface
)
62 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap(iface
);
63 ULONG refcount
= InterlockedDecrement(&bitmap
->refcount
);
65 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
69 ID3D10ShaderResourceView_Release(bitmap
->view
);
70 HeapFree(GetProcessHeap(), 0, bitmap
);
76 static void STDMETHODCALLTYPE
d2d_bitmap_GetFactory(ID2D1Bitmap
*iface
, ID2D1Factory
**factory
)
78 FIXME("iface %p, factory %p stub!\n", iface
, factory
);
83 static D2D1_SIZE_F
* STDMETHODCALLTYPE
d2d_bitmap_GetSize(ID2D1Bitmap
*iface
, D2D1_SIZE_F
*size
)
85 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap(iface
);
87 TRACE("iface %p, size %p.\n", iface
, size
);
89 size
->width
= bitmap
->pixel_size
.width
/ (bitmap
->dpi_x
/ 96.0f
);
90 size
->height
= bitmap
->pixel_size
.height
/ (bitmap
->dpi_y
/ 96.0f
);
94 static D2D1_SIZE_U
* STDMETHODCALLTYPE
d2d_bitmap_GetPixelSize(ID2D1Bitmap
*iface
, D2D1_SIZE_U
*pixel_size
)
96 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap(iface
);
98 TRACE("iface %p, pixel_size %p.\n", iface
, pixel_size
);
100 *pixel_size
= bitmap
->pixel_size
;
104 static D2D1_PIXEL_FORMAT
* STDMETHODCALLTYPE
d2d_bitmap_GetPixelFormat(ID2D1Bitmap
*iface
, D2D1_PIXEL_FORMAT
*format
)
106 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap(iface
);
108 TRACE("iface %p, format %p.\n", iface
, format
);
110 *format
= bitmap
->format
;
114 static void STDMETHODCALLTYPE
d2d_bitmap_GetDpi(ID2D1Bitmap
*iface
, float *dpi_x
, float *dpi_y
)
116 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap(iface
);
118 TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface
, dpi_x
, dpi_y
);
120 *dpi_x
= bitmap
->dpi_x
;
121 *dpi_y
= bitmap
->dpi_y
;
124 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_CopyFromBitmap(ID2D1Bitmap
*iface
,
125 const D2D1_POINT_2U
*dst_point
, ID2D1Bitmap
*bitmap
, const D2D1_RECT_U
*src_rect
)
127 FIXME("iface %p, dst_point %p, bitmap %p, src_rect %p stub!\n", iface
, dst_point
, bitmap
, src_rect
);
132 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_CopyFromRenderTarget(ID2D1Bitmap
*iface
,
133 const D2D1_POINT_2U
*dst_point
, ID2D1RenderTarget
*render_target
, const D2D1_RECT_U
*src_rect
)
135 FIXME("iface %p, dst_point %p, render_target %p, src_rect %p stub!\n", iface
, dst_point
, render_target
, src_rect
);
140 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_CopyFromMemory(ID2D1Bitmap
*iface
,
141 const D2D1_RECT_U
*dst_rect
, const void *src_data
, UINT32 pitch
)
143 FIXME("iface %p, dst_rect %p, src_data %p, pitch %u stub!\n", iface
, dst_rect
, src_data
, pitch
);
148 static const struct ID2D1BitmapVtbl d2d_bitmap_vtbl
=
150 d2d_bitmap_QueryInterface
,
153 d2d_bitmap_GetFactory
,
155 d2d_bitmap_GetPixelSize
,
156 d2d_bitmap_GetPixelFormat
,
158 d2d_bitmap_CopyFromBitmap
,
159 d2d_bitmap_CopyFromRenderTarget
,
160 d2d_bitmap_CopyFromMemory
,
163 HRESULT
d2d_bitmap_init(struct d2d_bitmap
*bitmap
, struct d2d_d3d_render_target
*render_target
,
164 D2D1_SIZE_U size
, const void *src_data
, UINT32 pitch
, const D2D1_BITMAP_PROPERTIES
*desc
)
166 D3D10_SUBRESOURCE_DATA resource_data
;
167 D3D10_TEXTURE2D_DESC texture_desc
;
168 ID3D10Texture2D
*texture
;
169 BOOL supported
= FALSE
;
173 static const D2D1_PIXEL_FORMAT supported_formats
[] =
175 {DXGI_FORMAT_R32G32B32A32_FLOAT
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
176 {DXGI_FORMAT_R32G32B32A32_FLOAT
, D2D1_ALPHA_MODE_IGNORE
},
177 {DXGI_FORMAT_R16G16B16A16_FLOAT
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
178 {DXGI_FORMAT_R16G16B16A16_FLOAT
, D2D1_ALPHA_MODE_IGNORE
},
179 {DXGI_FORMAT_R16G16B16A16_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
180 {DXGI_FORMAT_R16G16B16A16_UNORM
, D2D1_ALPHA_MODE_IGNORE
},
181 {DXGI_FORMAT_R8G8B8A8_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
182 {DXGI_FORMAT_R8G8B8A8_UNORM
, D2D1_ALPHA_MODE_IGNORE
},
183 {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
184 {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, D2D1_ALPHA_MODE_IGNORE
},
185 {DXGI_FORMAT_A8_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
186 {DXGI_FORMAT_A8_UNORM
, D2D1_ALPHA_MODE_STRAIGHT
},
187 {DXGI_FORMAT_B8G8R8A8_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
188 {DXGI_FORMAT_B8G8R8A8_UNORM
, D2D1_ALPHA_MODE_IGNORE
},
189 {DXGI_FORMAT_B8G8R8X8_UNORM
, D2D1_ALPHA_MODE_IGNORE
},
190 {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
191 {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
, D2D1_ALPHA_MODE_IGNORE
},
194 for (i
= 0; i
< sizeof(supported_formats
) / sizeof(*supported_formats
); ++i
)
196 if (supported_formats
[i
].format
== desc
->pixelFormat
.format
197 && supported_formats
[i
].alphaMode
== desc
->pixelFormat
.alphaMode
)
206 WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n",
207 desc
->pixelFormat
.format
, desc
->pixelFormat
.alphaMode
);
208 return D2DERR_UNSUPPORTED_PIXEL_FORMAT
;
211 FIXME("Ignoring bitmap properties.\n");
213 bitmap
->ID2D1Bitmap_iface
.lpVtbl
= &d2d_bitmap_vtbl
;
214 bitmap
->refcount
= 1;
216 texture_desc
.Width
= size
.width
;
217 texture_desc
.Height
= size
.height
;
218 texture_desc
.MipLevels
= 1;
219 texture_desc
.ArraySize
= 1;
220 texture_desc
.Format
= desc
->pixelFormat
.format
;
221 texture_desc
.SampleDesc
.Count
= 1;
222 texture_desc
.SampleDesc
.Quality
= 0;
223 texture_desc
.Usage
= D3D10_USAGE_DEFAULT
;
224 texture_desc
.BindFlags
= D3D10_BIND_SHADER_RESOURCE
;
225 texture_desc
.CPUAccessFlags
= 0;
226 texture_desc
.MiscFlags
= 0;
228 resource_data
.pSysMem
= src_data
;
229 resource_data
.SysMemPitch
= pitch
;
231 if (FAILED(hr
= ID3D10Device_CreateTexture2D(render_target
->device
, &texture_desc
,
232 src_data
? &resource_data
: NULL
, &texture
)))
234 ERR("Failed to create texture, hr %#x.\n", hr
);
238 hr
= ID3D10Device_CreateShaderResourceView(render_target
->device
, (ID3D10Resource
*)texture
, NULL
, &bitmap
->view
);
239 ID3D10Texture2D_Release(texture
);
242 ERR("Failed to create view, hr %#x.\n", hr
);
246 bitmap
->pixel_size
= size
;
247 bitmap
->format
= desc
->pixelFormat
;
248 bitmap
->dpi_x
= desc
->dpiX
;
249 bitmap
->dpi_y
= desc
->dpiY
;
251 if (bitmap
->dpi_x
== 0.0f
&& bitmap
->dpi_y
== 0.0f
)
253 bitmap
->dpi_x
= 96.0f
;
254 bitmap
->dpi_y
= 96.0f
;
260 struct d2d_bitmap
*unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap
*iface
)
264 assert(iface
->lpVtbl
== &d2d_bitmap_vtbl
);
265 return CONTAINING_RECORD(iface
, struct d2d_bitmap
, ID2D1Bitmap_iface
);