d2d1: Implement d2d_d3d_render_target_Clear().
[wine/multimedia.git] / dlls / d2d1 / render_target.c
blob3e5908656935c5105d98b8b2836419fc5328a641
1 /*
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
19 #include "config.h"
20 #include "wine/port.h"
22 #include "d2d1_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(d2d);
26 static inline struct d2d_d3d_render_target *impl_from_ID2D1RenderTarget(ID2D1RenderTarget *iface)
28 return CONTAINING_RECORD(iface, struct d2d_d3d_render_target, ID2D1RenderTarget_iface);
31 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_QueryInterface(ID2D1RenderTarget *iface, REFIID iid, void **out)
33 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
35 if (IsEqualGUID(iid, &IID_ID2D1RenderTarget)
36 || IsEqualGUID(iid, &IID_ID2D1Resource)
37 || IsEqualGUID(iid, &IID_IUnknown))
39 ID2D1RenderTarget_AddRef(iface);
40 *out = iface;
41 return S_OK;
44 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
46 *out = NULL;
47 return E_NOINTERFACE;
50 static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_AddRef(ID2D1RenderTarget *iface)
52 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
53 ULONG refcount = InterlockedIncrement(&render_target->refcount);
55 TRACE("%p increasing refcount to %u.\n", iface, refcount);
57 return refcount;
60 static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_Release(ID2D1RenderTarget *iface)
62 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
63 ULONG refcount = InterlockedDecrement(&render_target->refcount);
65 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
67 if (!refcount)
69 ID3D10RenderTargetView_Release(render_target->view);
70 ID3D10PixelShader_Release(render_target->clear_ps);
71 ID3D10VertexShader_Release(render_target->clear_vs);
72 ID3D10Buffer_Release(render_target->clear_vb);
73 ID3D10InputLayout_Release(render_target->clear_il);
74 render_target->stateblock->lpVtbl->Release(render_target->stateblock);
75 ID3D10Device_Release(render_target->device);
76 HeapFree(GetProcessHeap(), 0, render_target);
79 return refcount;
82 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetFactory(ID2D1RenderTarget *iface, ID2D1Factory **factory)
84 FIXME("iface %p, factory %p stub!\n", iface, factory);
86 *factory = NULL;
89 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmap(ID2D1RenderTarget *iface,
90 D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
92 FIXME("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p stub!\n",
93 iface, size.width, size.height, src_data, pitch, desc, bitmap);
95 return E_NOTIMPL;
98 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapFromWicBitmap(ID2D1RenderTarget *iface,
99 IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
101 FIXME("iface %p, bitmap_source %p, desc %p, bitmap %p stub!\n",
102 iface, bitmap_source, desc, bitmap);
104 return E_NOTIMPL;
107 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1RenderTarget *iface,
108 REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
110 FIXME("iface %p, iid %s, data %p, desc %p, bitmap %p stub!\n",
111 iface, debugstr_guid(iid), data, desc, bitmap);
113 return E_NOTIMPL;
116 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapBrush(ID2D1RenderTarget *iface,
117 ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc,
118 const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush)
120 FIXME("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p stub!\n",
121 iface, bitmap, bitmap_brush_desc, brush_desc, brush);
123 return E_NOTIMPL;
126 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSolidColorBrush(ID2D1RenderTarget *iface,
127 const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush)
129 struct d2d_brush *object;
131 TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush);
133 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
134 return E_OUTOFMEMORY;
136 d2d_solid_color_brush_init(object, iface, color, desc);
138 TRACE("Created brush %p.\n", object);
139 *brush = (ID2D1SolidColorBrush *)&object->ID2D1Brush_iface;
141 return S_OK;
144 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateGradientStopCollection(ID2D1RenderTarget *iface,
145 const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode,
146 ID2D1GradientStopCollection **gradient)
148 struct d2d_gradient *object;
150 TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n",
151 iface, stops, stop_count, gamma, extend_mode, gradient);
153 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
154 return E_OUTOFMEMORY;
156 d2d_gradient_init(object, iface, stops, stop_count, gamma, extend_mode);
158 TRACE("Created gradient %p.\n", object);
159 *gradient = &object->ID2D1GradientStopCollection_iface;
161 return S_OK;
164 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLinearGradientBrush(ID2D1RenderTarget *iface,
165 const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
166 ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush)
168 struct d2d_brush *object;
170 TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
171 iface, gradient_brush_desc, brush_desc, gradient, brush);
173 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
174 return E_OUTOFMEMORY;
176 d2d_linear_gradient_brush_init(object, iface, gradient_brush_desc, brush_desc, gradient);
178 TRACE("Created brush %p.\n", object);
179 *brush = (ID2D1LinearGradientBrush *)&object->ID2D1Brush_iface;
181 return S_OK;
184 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateRadialGradientBrush(ID2D1RenderTarget *iface,
185 const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
186 ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush)
188 FIXME("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p stub!\n",
189 iface, gradient_brush_desc, brush_desc, gradient, brush);
191 return E_NOTIMPL;
194 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateCompatibleRenderTarget(ID2D1RenderTarget *iface,
195 const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format,
196 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target)
198 FIXME("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p stub!\n",
199 iface, size, pixel_size, format, options, render_target);
201 return E_NOTIMPL;
204 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLayer(ID2D1RenderTarget *iface,
205 const D2D1_SIZE_F *size, ID2D1Layer **layer)
207 FIXME("iface %p, size %p, layer %p stub!\n", iface, size, layer);
209 return E_NOTIMPL;
212 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateMesh(ID2D1RenderTarget *iface, ID2D1Mesh **mesh)
214 FIXME("iface %p, mesh %p stub!\n", iface, mesh);
216 return E_NOTIMPL;
219 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawLine(ID2D1RenderTarget *iface,
220 D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
222 FIXME("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
223 iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style);
226 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRectangle(ID2D1RenderTarget *iface,
227 const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
229 FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
230 iface, rect, brush, stroke_width, stroke_style);
233 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTarget *iface,
234 const D2D1_RECT_F *rect, ID2D1Brush *brush)
236 FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
239 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRoundedRectangle(ID2D1RenderTarget *iface,
240 const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
242 FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
243 iface, rect, brush, stroke_width, stroke_style);
246 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRoundedRectangle(ID2D1RenderTarget *iface,
247 const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush)
249 FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
252 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawEllipse(ID2D1RenderTarget *iface,
253 const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
255 FIXME("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
256 iface, ellipse, brush, stroke_width, stroke_style);
259 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillEllipse(ID2D1RenderTarget *iface,
260 const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush)
262 FIXME("iface %p, ellipse %p, brush %p stub!\n", iface, ellipse, brush);
265 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGeometry(ID2D1RenderTarget *iface,
266 ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
268 FIXME("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
269 iface, geometry, brush, stroke_width, stroke_style);
272 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarget *iface,
273 ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush)
275 FIXME("iface %p, geometry %p, brush %p, opacity_brush %p stub!\n", iface, geometry, brush, opacity_brush);
278 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillMesh(ID2D1RenderTarget *iface,
279 ID2D1Mesh *mesh, ID2D1Brush *brush)
281 FIXME("iface %p, mesh %p, brush %p stub!\n", iface, mesh, brush);
284 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillOpacityMask(ID2D1RenderTarget *iface,
285 ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content,
286 const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect)
288 FIXME("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p stub!\n",
289 iface, mask, brush, content, dst_rect, src_rect);
292 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawBitmap(ID2D1RenderTarget *iface,
293 ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity,
294 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect)
296 FIXME("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p stub!\n",
297 iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect);
300 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawText(ID2D1RenderTarget *iface,
301 const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect,
302 ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode)
304 FIXME("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, "
305 "brush %p, options %#x, measuring_mode %#x stub!\n",
306 iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect,
307 brush, options, measuring_mode);
310 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawTextLayout(ID2D1RenderTarget *iface,
311 D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options)
313 FIXME("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x stub!\n",
314 iface, origin.x, origin.y, layout, brush, options);
317 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarget *iface,
318 D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
319 DWRITE_MEASURING_MODE measuring_mode)
321 FIXME("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x stub!\n",
322 iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode);
325 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTransform(ID2D1RenderTarget *iface,
326 const D2D1_MATRIX_3X2_F *transform)
328 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
330 TRACE("iface %p, transform %p.\n", iface, transform);
332 render_target->transform = *transform;
335 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTransform(ID2D1RenderTarget *iface,
336 D2D1_MATRIX_3X2_F *transform)
338 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
340 TRACE("iface %p, transform %p.\n", iface, transform);
342 *transform = render_target->transform;
345 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetAntialiasMode(ID2D1RenderTarget *iface,
346 D2D1_ANTIALIAS_MODE antialias_mode)
348 FIXME("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
351 static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetAntialiasMode(ID2D1RenderTarget *iface)
353 FIXME("iface %p stub!\n", iface);
355 return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
358 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextAntialiasMode(ID2D1RenderTarget *iface,
359 D2D1_TEXT_ANTIALIAS_MODE antialias_mode)
361 FIXME("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
364 static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetTextAntialiasMode(ID2D1RenderTarget *iface)
366 FIXME("iface %p stub!\n", iface);
368 return D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
371 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextRenderingParams(ID2D1RenderTarget *iface,
372 IDWriteRenderingParams *text_rendering_params)
374 FIXME("iface %p, text_rendering_params %p stub!\n", iface, text_rendering_params);
377 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTextRenderingParams(ID2D1RenderTarget *iface,
378 IDWriteRenderingParams **text_rendering_params)
380 FIXME("iface %p, text_rendering_params %p stub!\n", iface, text_rendering_params);
382 *text_rendering_params = NULL;
385 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTags(ID2D1RenderTarget *iface, D2D1_TAG tag1, D2D1_TAG tag2)
387 FIXME("iface %p, tag1 %s, tag2 %s stub!\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2));
390 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTags(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
392 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
394 *tag1 = 0;
395 *tag2 = 0;
398 static void STDMETHODCALLTYPE d2d_d3d_render_target_PushLayer(ID2D1RenderTarget *iface,
399 const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer)
401 FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer);
404 static void STDMETHODCALLTYPE d2d_d3d_render_target_PopLayer(ID2D1RenderTarget *iface)
406 FIXME("iface %p stub!\n", iface);
409 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_Flush(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
411 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
413 return E_NOTIMPL;
416 static void STDMETHODCALLTYPE d2d_d3d_render_target_SaveDrawingState(ID2D1RenderTarget *iface,
417 ID2D1DrawingStateBlock *state_block)
419 FIXME("iface %p, state_block %p stub!\n", iface, state_block);
422 static void STDMETHODCALLTYPE d2d_d3d_render_target_RestoreDrawingState(ID2D1RenderTarget *iface,
423 ID2D1DrawingStateBlock *state_block)
425 FIXME("iface %p, state_block %p stub!\n", iface, state_block);
428 static void STDMETHODCALLTYPE d2d_d3d_render_target_PushAxisAlignedClip(ID2D1RenderTarget *iface,
429 const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode)
431 FIXME("iface %p, clip_rect %p, antialias_mode %#x stub!\n", iface, clip_rect, antialias_mode);
434 static void STDMETHODCALLTYPE d2d_d3d_render_target_PopAxisAlignedClip(ID2D1RenderTarget *iface)
436 FIXME("iface %p stub!\n", iface);
439 static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *iface, const D2D1_COLOR_F *color)
441 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
442 D3D10_SUBRESOURCE_DATA buffer_data;
443 D3D10_BUFFER_DESC buffer_desc;
444 unsigned int offset;
445 D3D10_VIEWPORT vp;
446 ID3D10Buffer *cb;
447 HRESULT hr;
449 TRACE("iface %p, color %p.\n", iface, color);
451 buffer_desc.ByteWidth = sizeof(*color);
452 buffer_desc.Usage = D3D10_USAGE_DEFAULT;
453 buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
454 buffer_desc.CPUAccessFlags = 0;
455 buffer_desc.MiscFlags = 0;
457 buffer_data.pSysMem = color;
458 buffer_data.SysMemPitch = 0;
459 buffer_data.SysMemSlicePitch = 0;
461 if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &cb)))
463 WARN("Failed to create constant buffer, hr %#x.\n", hr);
464 return;
467 vp.TopLeftX = 0;
468 vp.TopLeftY = 0;
469 vp.Width = render_target->pixel_size.width;
470 vp.Height = render_target->pixel_size.height;
471 vp.MinDepth = 0.0f;
472 vp.MaxDepth = 1.0f;
474 if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock)))
476 WARN("Failed to capture stateblock, hr %#x.\n", hr);
477 ID3D10Buffer_Release(cb);
478 return;
481 ID3D10Device_ClearState(render_target->device);
483 ID3D10Device_IASetInputLayout(render_target->device, render_target->clear_il);
484 ID3D10Device_IASetPrimitiveTopology(render_target->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
485 offset = 0;
486 ID3D10Device_IASetVertexBuffers(render_target->device, 0, 1,
487 &render_target->clear_vb, &render_target->clear_vb_stride, &offset);
488 ID3D10Device_VSSetShader(render_target->device, render_target->clear_vs);
489 ID3D10Device_PSSetConstantBuffers(render_target->device, 0, 1, &cb);
490 ID3D10Device_PSSetShader(render_target->device, render_target->clear_ps);
491 ID3D10Device_RSSetViewports(render_target->device, 1, &vp);
492 ID3D10Device_OMSetRenderTargets(render_target->device, 1, &render_target->view, NULL);
494 ID3D10Device_Draw(render_target->device, 4, 0);
496 if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock)))
497 WARN("Failed to apply stateblock, hr %#x.\n", hr);
499 ID3D10Buffer_Release(cb);
502 static void STDMETHODCALLTYPE d2d_d3d_render_target_BeginDraw(ID2D1RenderTarget *iface)
504 TRACE("iface %p.\n", iface);
507 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_EndDraw(ID2D1RenderTarget *iface,
508 D2D1_TAG *tag1, D2D1_TAG *tag2)
510 TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
512 if (tag1)
513 *tag1 = 0;
514 if (tag2)
515 *tag2 = 0;
517 return S_OK;
520 static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelFormat(ID2D1RenderTarget *iface,
521 D2D1_PIXEL_FORMAT *format)
523 FIXME("iface %p, format %p stub!\n", iface, format);
525 format->format = DXGI_FORMAT_UNKNOWN;
526 format->alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
527 return format;
530 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetDpi(ID2D1RenderTarget *iface, float dpi_x, float dpi_y)
532 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
534 TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y);
536 if (dpi_x == 0.0f && dpi_y == 0.0f)
538 dpi_x = 96.0f;
539 dpi_y = 96.0f;
542 render_target->dpi_x = dpi_x;
543 render_target->dpi_y = dpi_y;
546 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *iface, float *dpi_x, float *dpi_y)
548 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
550 TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y);
552 *dpi_x = render_target->dpi_x;
553 *dpi_y = render_target->dpi_y;
556 static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface, D2D1_SIZE_F *size)
558 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
560 TRACE("iface %p, size %p.\n", iface, size);
562 size->width = render_target->pixel_size.width / (render_target->dpi_x / 96.0f);
563 size->height = render_target->pixel_size.height / (render_target->dpi_y / 96.0f);
564 return size;
567 static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelSize(ID2D1RenderTarget *iface,
568 D2D1_SIZE_U *pixel_size)
570 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
572 TRACE("iface %p, pixel_size %p.\n", iface, pixel_size);
574 *pixel_size = render_target->pixel_size;
575 return pixel_size;
578 static UINT32 STDMETHODCALLTYPE d2d_d3d_render_target_GetMaximumBitmapSize(ID2D1RenderTarget *iface)
580 FIXME("iface %p stub!\n", iface);
582 return 0;
585 static BOOL STDMETHODCALLTYPE d2d_d3d_render_target_IsSupported(ID2D1RenderTarget *iface,
586 const D2D1_RENDER_TARGET_PROPERTIES *desc)
588 FIXME("iface %p, desc %p stub!\n", iface, desc);
590 return FALSE;
593 static const struct ID2D1RenderTargetVtbl d2d_d3d_render_target_vtbl =
595 d2d_d3d_render_target_QueryInterface,
596 d2d_d3d_render_target_AddRef,
597 d2d_d3d_render_target_Release,
598 d2d_d3d_render_target_GetFactory,
599 d2d_d3d_render_target_CreateBitmap,
600 d2d_d3d_render_target_CreateBitmapFromWicBitmap,
601 d2d_d3d_render_target_CreateSharedBitmap,
602 d2d_d3d_render_target_CreateBitmapBrush,
603 d2d_d3d_render_target_CreateSolidColorBrush,
604 d2d_d3d_render_target_CreateGradientStopCollection,
605 d2d_d3d_render_target_CreateLinearGradientBrush,
606 d2d_d3d_render_target_CreateRadialGradientBrush,
607 d2d_d3d_render_target_CreateCompatibleRenderTarget,
608 d2d_d3d_render_target_CreateLayer,
609 d2d_d3d_render_target_CreateMesh,
610 d2d_d3d_render_target_DrawLine,
611 d2d_d3d_render_target_DrawRectangle,
612 d2d_d3d_render_target_FillRectangle,
613 d2d_d3d_render_target_DrawRoundedRectangle,
614 d2d_d3d_render_target_FillRoundedRectangle,
615 d2d_d3d_render_target_DrawEllipse,
616 d2d_d3d_render_target_FillEllipse,
617 d2d_d3d_render_target_DrawGeometry,
618 d2d_d3d_render_target_FillGeometry,
619 d2d_d3d_render_target_FillMesh,
620 d2d_d3d_render_target_FillOpacityMask,
621 d2d_d3d_render_target_DrawBitmap,
622 d2d_d3d_render_target_DrawText,
623 d2d_d3d_render_target_DrawTextLayout,
624 d2d_d3d_render_target_DrawGlyphRun,
625 d2d_d3d_render_target_SetTransform,
626 d2d_d3d_render_target_GetTransform,
627 d2d_d3d_render_target_SetAntialiasMode,
628 d2d_d3d_render_target_GetAntialiasMode,
629 d2d_d3d_render_target_SetTextAntialiasMode,
630 d2d_d3d_render_target_GetTextAntialiasMode,
631 d2d_d3d_render_target_SetTextRenderingParams,
632 d2d_d3d_render_target_GetTextRenderingParams,
633 d2d_d3d_render_target_SetTags,
634 d2d_d3d_render_target_GetTags,
635 d2d_d3d_render_target_PushLayer,
636 d2d_d3d_render_target_PopLayer,
637 d2d_d3d_render_target_Flush,
638 d2d_d3d_render_target_SaveDrawingState,
639 d2d_d3d_render_target_RestoreDrawingState,
640 d2d_d3d_render_target_PushAxisAlignedClip,
641 d2d_d3d_render_target_PopAxisAlignedClip,
642 d2d_d3d_render_target_Clear,
643 d2d_d3d_render_target_BeginDraw,
644 d2d_d3d_render_target_EndDraw,
645 d2d_d3d_render_target_GetPixelFormat,
646 d2d_d3d_render_target_SetDpi,
647 d2d_d3d_render_target_GetDpi,
648 d2d_d3d_render_target_GetSize,
649 d2d_d3d_render_target_GetPixelSize,
650 d2d_d3d_render_target_GetMaximumBitmapSize,
651 d2d_d3d_render_target_IsSupported,
654 HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
655 IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
657 D3D10_SUBRESOURCE_DATA buffer_data;
658 D3D10_STATE_BLOCK_MASK state_mask;
659 DXGI_SURFACE_DESC surface_desc;
660 D3D10_BUFFER_DESC buffer_desc;
661 ID3D10Resource *resource;
662 HRESULT hr;
664 static const D3D10_INPUT_ELEMENT_DESC clear_il_desc[] =
666 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
668 static const DWORD clear_vs_code[] =
670 /* float4 main(float4 position : POSITION) : SV_POSITION
672 * return position;
673 * } */
674 0x43425844, 0x1fa8c27f, 0x52d2f21d, 0xc196fdb7, 0x376f283a, 0x00000001, 0x000001b4, 0x00000005,
675 0x00000034, 0x0000008c, 0x000000c0, 0x000000f4, 0x00000138, 0x46454452, 0x00000050, 0x00000000,
676 0x00000000, 0x00000000, 0x0000001c, 0xfffe0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
677 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e,
678 0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
679 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
680 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
681 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
682 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
683 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074,
684 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
685 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
686 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
687 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
689 static const DWORD clear_ps_code[] =
691 /* float4 color;
693 * float4 main(float4 position : SV_POSITION) : SV_Target
695 * return color;
696 * } */
697 0x43425844, 0xecd3cc9d, 0x0025bc77, 0x7a333165, 0x5b04c7e4, 0x00000001, 0x0000022c, 0x00000005,
698 0x00000034, 0x00000100, 0x00000134, 0x00000168, 0x000001b0, 0x46454452, 0x000000c4, 0x00000001,
699 0x00000048, 0x00000001, 0x0000001c, 0xffff0400, 0x00000100, 0x00000090, 0x0000003c, 0x00000000,
700 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x6f6c4724, 0x736c6162,
701 0xababab00, 0x0000003c, 0x00000001, 0x00000060, 0x00000010, 0x00000000, 0x00000000, 0x00000078,
702 0x00000000, 0x00000010, 0x00000002, 0x00000080, 0x00000000, 0x6f6c6f63, 0xabab0072, 0x00030001,
703 0x00040001, 0x00000000, 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53,
704 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
705 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
706 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001,
707 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
708 0x65677261, 0xabab0074, 0x52444853, 0x00000040, 0x00000040, 0x00000010, 0x04000059, 0x00208e46,
709 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x06000036, 0x001020f2, 0x00000000,
710 0x00208e46, 0x00000000, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
711 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
712 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
713 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
714 0x00000000, 0x00000000, 0x00000000,
716 static const struct
718 float x, y;
720 clear_quad[] =
722 {-1.0f, -1.0f},
723 {-1.0f, 1.0f},
724 { 1.0f, -1.0f},
725 { 1.0f, 1.0f},
727 static const D2D1_MATRIX_3X2_F identity =
729 1.0f, 0.0f,
730 0.0f, 1.0f,
731 0.0f, 0.0f,
734 FIXME("Ignoring render target properties.\n");
736 render_target->ID2D1RenderTarget_iface.lpVtbl = &d2d_d3d_render_target_vtbl;
737 render_target->refcount = 1;
739 if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
741 WARN("Failed to get device interface, hr %#x.\n", hr);
742 return hr;
745 if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
747 WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
748 goto err;
751 hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &render_target->view);
752 ID3D10Resource_Release(resource);
753 if (FAILED(hr))
755 WARN("Failed to create rendertarget view, hr %#x.\n", hr);
756 goto err;
759 if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask)))
761 WARN("Failed to create stateblock mask, hr %#x.\n", hr);
762 goto err;
765 if (FAILED(hr = D3D10CreateStateBlock(render_target->device, &state_mask, &render_target->stateblock)))
767 WARN("Failed to create stateblock, hr %#x.\n", hr);
768 goto err;
771 if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->device, clear_il_desc,
772 sizeof(clear_il_desc) / sizeof(*clear_il_desc), clear_vs_code, sizeof(clear_vs_code),
773 &render_target->clear_il)))
775 WARN("Failed to create clear input layout, hr %#x.\n", hr);
776 goto err;
779 buffer_desc.ByteWidth = sizeof(clear_quad);
780 buffer_desc.Usage = D3D10_USAGE_DEFAULT;
781 buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
782 buffer_desc.CPUAccessFlags = 0;
783 buffer_desc.MiscFlags = 0;
785 buffer_data.pSysMem = clear_quad;
786 buffer_data.SysMemPitch = 0;
787 buffer_data.SysMemSlicePitch = 0;
789 render_target->clear_vb_stride = sizeof(*clear_quad);
790 if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device,
791 &buffer_desc, &buffer_data, &render_target->clear_vb)))
793 WARN("Failed to create clear vertex buffer, hr %#x.\n", hr);
794 goto err;
797 if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->device,
798 clear_vs_code, sizeof(clear_vs_code), &render_target->clear_vs)))
800 WARN("Failed to create clear vertex shader, hr %#x.\n", hr);
801 goto err;
804 if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
805 clear_ps_code, sizeof(clear_ps_code), &render_target->clear_ps)))
807 WARN("Failed to create clear pixel shader, hr %#x.\n", hr);
808 goto err;
811 if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
813 WARN("Failed to get surface desc, hr %#x.\n", hr);
814 goto err;
817 render_target->pixel_size.width = surface_desc.Width;
818 render_target->pixel_size.height = surface_desc.Height;
819 render_target->transform = identity;
820 render_target->dpi_x = desc->dpiX;
821 render_target->dpi_y = desc->dpiY;
823 if (render_target->dpi_x == 0.0f && render_target->dpi_y == 0.0f)
825 render_target->dpi_x = 96.0f;
826 render_target->dpi_y = 96.0f;
829 return S_OK;
831 err:
832 if (render_target->view)
833 ID3D10RenderTargetView_Release(render_target->view);
834 if (render_target->clear_ps)
835 ID3D10PixelShader_Release(render_target->clear_ps);
836 if (render_target->clear_vs)
837 ID3D10VertexShader_Release(render_target->clear_vs);
838 if (render_target->clear_vb)
839 ID3D10Buffer_Release(render_target->clear_vb);
840 if (render_target->clear_il)
841 ID3D10InputLayout_Release(render_target->clear_il);
842 if (render_target->stateblock)
843 render_target->stateblock->lpVtbl->Release(render_target->stateblock);
844 if (render_target->device)
845 ID3D10Device_Release(render_target->device);
846 return hr;