d2d1: Implement d2d_d3d_render_target_CreateMesh().
[wine/multimedia.git] / dlls / d2d1 / render_target.c
blob8a55890d9878efe21d790d9b1ea996209e064b43
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 #define INITIAL_CLIP_STACK_SIZE 4
28 static void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y)
30 dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31;
31 dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32;
34 static void d2d_rect_expand(D2D1_RECT_F *dst, const D2D1_POINT_2F *point)
36 if (point->x < dst->left)
37 dst->left = point->x;
38 if (point->y < dst->top)
39 dst->top = point->y;
40 if (point->x > dst->right)
41 dst->right = point->x;
42 if (point->y > dst->bottom)
43 dst->bottom = point->y;
46 static void d2d_rect_intersect(D2D1_RECT_F *dst, const D2D1_RECT_F *src)
48 if (src->left > dst->left)
49 dst->left = src->left;
50 if (src->top > dst->top)
51 dst->top = src->top;
52 if (src->right < dst->right)
53 dst->right = src->right;
54 if (src->bottom < dst->bottom)
55 dst->bottom = src->bottom;
58 static void d2d_rect_set(D2D1_RECT_F *dst, float left, float top, float right, float bottom)
60 dst->left = left;
61 dst->top = top;
62 dst->right = right;
63 dst->bottom = bottom;
66 static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack)
68 if (!(stack->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack))))
69 return FALSE;
71 stack->size = INITIAL_CLIP_STACK_SIZE;
72 stack->count = 0;
74 return TRUE;
77 static void d2d_clip_stack_cleanup(struct d2d_clip_stack *stack)
79 HeapFree(GetProcessHeap(), 0, stack->stack);
82 static BOOL d2d_clip_stack_push(struct d2d_clip_stack *stack, const D2D1_RECT_F *rect)
84 D2D1_RECT_F r;
86 if (stack->count == stack->size)
88 D2D1_RECT_F *new_stack;
89 unsigned int new_size;
91 if (stack->size > UINT_MAX / 2)
92 return FALSE;
94 new_size = stack->size * 2;
95 if (!(new_stack = HeapReAlloc(GetProcessHeap(), 0, stack->stack, new_size * sizeof(*stack->stack))))
96 return FALSE;
98 stack->stack = new_stack;
99 stack->size = new_size;
102 r = *rect;
103 if (stack->count)
104 d2d_rect_intersect(&r, &stack->stack[stack->count - 1]);
105 stack->stack[stack->count++] = r;
107 return TRUE;
110 static void d2d_clip_stack_pop(struct d2d_clip_stack *stack)
112 if (!stack->count)
113 return;
114 --stack->count;
117 static inline struct d2d_d3d_render_target *impl_from_ID2D1RenderTarget(ID2D1RenderTarget *iface)
119 return CONTAINING_RECORD(iface, struct d2d_d3d_render_target, ID2D1RenderTarget_iface);
122 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_QueryInterface(ID2D1RenderTarget *iface, REFIID iid, void **out)
124 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
126 if (IsEqualGUID(iid, &IID_ID2D1RenderTarget)
127 || IsEqualGUID(iid, &IID_ID2D1Resource)
128 || IsEqualGUID(iid, &IID_IUnknown))
130 ID2D1RenderTarget_AddRef(iface);
131 *out = iface;
132 return S_OK;
135 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
137 *out = NULL;
138 return E_NOINTERFACE;
141 static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_AddRef(ID2D1RenderTarget *iface)
143 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
144 ULONG refcount = InterlockedIncrement(&render_target->refcount);
146 TRACE("%p increasing refcount to %u.\n", iface, refcount);
148 return refcount;
151 static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_Release(ID2D1RenderTarget *iface)
153 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
154 ULONG refcount = InterlockedDecrement(&render_target->refcount);
156 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
158 if (!refcount)
160 d2d_clip_stack_cleanup(&render_target->clip_stack);
161 ID3D10RenderTargetView_Release(render_target->view);
162 ID3D10RasterizerState_Release(render_target->clear_rs);
163 ID3D10PixelShader_Release(render_target->clear_ps);
164 ID3D10VertexShader_Release(render_target->clear_vs);
165 ID3D10Buffer_Release(render_target->clear_vb);
166 ID3D10InputLayout_Release(render_target->clear_il);
167 render_target->stateblock->lpVtbl->Release(render_target->stateblock);
168 ID3D10Device_Release(render_target->device);
169 HeapFree(GetProcessHeap(), 0, render_target);
172 return refcount;
175 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetFactory(ID2D1RenderTarget *iface, ID2D1Factory **factory)
177 FIXME("iface %p, factory %p stub!\n", iface, factory);
179 *factory = NULL;
182 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmap(ID2D1RenderTarget *iface,
183 D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
185 FIXME("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p stub!\n",
186 iface, size.width, size.height, src_data, pitch, desc, bitmap);
188 return E_NOTIMPL;
191 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapFromWicBitmap(ID2D1RenderTarget *iface,
192 IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
194 FIXME("iface %p, bitmap_source %p, desc %p, bitmap %p stub!\n",
195 iface, bitmap_source, desc, bitmap);
197 return E_NOTIMPL;
200 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1RenderTarget *iface,
201 REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
203 FIXME("iface %p, iid %s, data %p, desc %p, bitmap %p stub!\n",
204 iface, debugstr_guid(iid), data, desc, bitmap);
206 return E_NOTIMPL;
209 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapBrush(ID2D1RenderTarget *iface,
210 ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc,
211 const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush)
213 FIXME("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p stub!\n",
214 iface, bitmap, bitmap_brush_desc, brush_desc, brush);
216 return E_NOTIMPL;
219 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSolidColorBrush(ID2D1RenderTarget *iface,
220 const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush)
222 struct d2d_brush *object;
224 TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush);
226 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
227 return E_OUTOFMEMORY;
229 d2d_solid_color_brush_init(object, iface, color, desc);
231 TRACE("Created brush %p.\n", object);
232 *brush = (ID2D1SolidColorBrush *)&object->ID2D1Brush_iface;
234 return S_OK;
237 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateGradientStopCollection(ID2D1RenderTarget *iface,
238 const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode,
239 ID2D1GradientStopCollection **gradient)
241 struct d2d_gradient *object;
243 TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n",
244 iface, stops, stop_count, gamma, extend_mode, gradient);
246 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
247 return E_OUTOFMEMORY;
249 d2d_gradient_init(object, iface, stops, stop_count, gamma, extend_mode);
251 TRACE("Created gradient %p.\n", object);
252 *gradient = &object->ID2D1GradientStopCollection_iface;
254 return S_OK;
257 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLinearGradientBrush(ID2D1RenderTarget *iface,
258 const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
259 ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush)
261 struct d2d_brush *object;
263 TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
264 iface, gradient_brush_desc, brush_desc, gradient, brush);
266 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
267 return E_OUTOFMEMORY;
269 d2d_linear_gradient_brush_init(object, iface, gradient_brush_desc, brush_desc, gradient);
271 TRACE("Created brush %p.\n", object);
272 *brush = (ID2D1LinearGradientBrush *)&object->ID2D1Brush_iface;
274 return S_OK;
277 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateRadialGradientBrush(ID2D1RenderTarget *iface,
278 const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
279 ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush)
281 FIXME("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p stub!\n",
282 iface, gradient_brush_desc, brush_desc, gradient, brush);
284 return E_NOTIMPL;
287 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateCompatibleRenderTarget(ID2D1RenderTarget *iface,
288 const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format,
289 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target)
291 FIXME("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p stub!\n",
292 iface, size, pixel_size, format, options, render_target);
294 return E_NOTIMPL;
297 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLayer(ID2D1RenderTarget *iface,
298 const D2D1_SIZE_F *size, ID2D1Layer **layer)
300 FIXME("iface %p, size %p, layer %p stub!\n", iface, size, layer);
302 return E_NOTIMPL;
305 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateMesh(ID2D1RenderTarget *iface, ID2D1Mesh **mesh)
307 struct d2d_mesh *object;
309 TRACE("iface %p, mesh %p.\n", iface, mesh);
311 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
312 return E_OUTOFMEMORY;
314 d2d_mesh_init(object);
316 TRACE("Created mesh %p.\n", object);
317 *mesh = &object->ID2D1Mesh_iface;
319 return S_OK;
322 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawLine(ID2D1RenderTarget *iface,
323 D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
325 FIXME("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
326 iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style);
329 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRectangle(ID2D1RenderTarget *iface,
330 const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
332 FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
333 iface, rect, brush, stroke_width, stroke_style);
336 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTarget *iface,
337 const D2D1_RECT_F *rect, ID2D1Brush *brush)
339 FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
342 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRoundedRectangle(ID2D1RenderTarget *iface,
343 const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
345 FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
346 iface, rect, brush, stroke_width, stroke_style);
349 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRoundedRectangle(ID2D1RenderTarget *iface,
350 const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush)
352 FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
355 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawEllipse(ID2D1RenderTarget *iface,
356 const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
358 FIXME("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
359 iface, ellipse, brush, stroke_width, stroke_style);
362 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillEllipse(ID2D1RenderTarget *iface,
363 const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush)
365 FIXME("iface %p, ellipse %p, brush %p stub!\n", iface, ellipse, brush);
368 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGeometry(ID2D1RenderTarget *iface,
369 ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
371 FIXME("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
372 iface, geometry, brush, stroke_width, stroke_style);
375 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarget *iface,
376 ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush)
378 FIXME("iface %p, geometry %p, brush %p, opacity_brush %p stub!\n", iface, geometry, brush, opacity_brush);
381 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillMesh(ID2D1RenderTarget *iface,
382 ID2D1Mesh *mesh, ID2D1Brush *brush)
384 FIXME("iface %p, mesh %p, brush %p stub!\n", iface, mesh, brush);
387 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillOpacityMask(ID2D1RenderTarget *iface,
388 ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content,
389 const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect)
391 FIXME("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p stub!\n",
392 iface, mask, brush, content, dst_rect, src_rect);
395 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawBitmap(ID2D1RenderTarget *iface,
396 ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity,
397 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect)
399 FIXME("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p stub!\n",
400 iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect);
403 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawText(ID2D1RenderTarget *iface,
404 const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect,
405 ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode)
407 FIXME("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, "
408 "brush %p, options %#x, measuring_mode %#x stub!\n",
409 iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect,
410 brush, options, measuring_mode);
413 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawTextLayout(ID2D1RenderTarget *iface,
414 D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options)
416 FIXME("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x stub!\n",
417 iface, origin.x, origin.y, layout, brush, options);
420 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarget *iface,
421 D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
422 DWRITE_MEASURING_MODE measuring_mode)
424 FIXME("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x stub!\n",
425 iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode);
428 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTransform(ID2D1RenderTarget *iface,
429 const D2D1_MATRIX_3X2_F *transform)
431 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
433 TRACE("iface %p, transform %p.\n", iface, transform);
435 render_target->transform = *transform;
438 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTransform(ID2D1RenderTarget *iface,
439 D2D1_MATRIX_3X2_F *transform)
441 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
443 TRACE("iface %p, transform %p.\n", iface, transform);
445 *transform = render_target->transform;
448 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetAntialiasMode(ID2D1RenderTarget *iface,
449 D2D1_ANTIALIAS_MODE antialias_mode)
451 FIXME("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
454 static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetAntialiasMode(ID2D1RenderTarget *iface)
456 FIXME("iface %p stub!\n", iface);
458 return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
461 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextAntialiasMode(ID2D1RenderTarget *iface,
462 D2D1_TEXT_ANTIALIAS_MODE antialias_mode)
464 FIXME("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
467 static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetTextAntialiasMode(ID2D1RenderTarget *iface)
469 FIXME("iface %p stub!\n", iface);
471 return D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
474 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextRenderingParams(ID2D1RenderTarget *iface,
475 IDWriteRenderingParams *text_rendering_params)
477 FIXME("iface %p, text_rendering_params %p stub!\n", iface, text_rendering_params);
480 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTextRenderingParams(ID2D1RenderTarget *iface,
481 IDWriteRenderingParams **text_rendering_params)
483 FIXME("iface %p, text_rendering_params %p stub!\n", iface, text_rendering_params);
485 *text_rendering_params = NULL;
488 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTags(ID2D1RenderTarget *iface, D2D1_TAG tag1, D2D1_TAG tag2)
490 FIXME("iface %p, tag1 %s, tag2 %s stub!\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2));
493 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTags(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
495 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
497 *tag1 = 0;
498 *tag2 = 0;
501 static void STDMETHODCALLTYPE d2d_d3d_render_target_PushLayer(ID2D1RenderTarget *iface,
502 const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer)
504 FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer);
507 static void STDMETHODCALLTYPE d2d_d3d_render_target_PopLayer(ID2D1RenderTarget *iface)
509 FIXME("iface %p stub!\n", iface);
512 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_Flush(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
514 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
516 return E_NOTIMPL;
519 static void STDMETHODCALLTYPE d2d_d3d_render_target_SaveDrawingState(ID2D1RenderTarget *iface,
520 ID2D1DrawingStateBlock *state_block)
522 FIXME("iface %p, state_block %p stub!\n", iface, state_block);
525 static void STDMETHODCALLTYPE d2d_d3d_render_target_RestoreDrawingState(ID2D1RenderTarget *iface,
526 ID2D1DrawingStateBlock *state_block)
528 FIXME("iface %p, state_block %p stub!\n", iface, state_block);
531 static void STDMETHODCALLTYPE d2d_d3d_render_target_PushAxisAlignedClip(ID2D1RenderTarget *iface,
532 const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode)
534 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
535 D2D1_RECT_F transformed_rect;
536 float x_scale, y_scale;
537 D2D1_POINT_2F point;
539 TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode);
541 if (antialias_mode != D2D1_ANTIALIAS_MODE_ALIASED)
542 FIXME("Ignoring antialias_mode %#x.\n", antialias_mode);
544 x_scale = render_target->dpi_x / 96.0f;
545 y_scale = render_target->dpi_y / 96.0f;
546 d2d_point_transform(&point, &render_target->transform, clip_rect->left * x_scale, clip_rect->top * y_scale);
547 d2d_rect_set(&transformed_rect, point.x, point.y, point.x, point.y);
548 d2d_point_transform(&point, &render_target->transform, clip_rect->left * x_scale, clip_rect->bottom * y_scale);
549 d2d_rect_expand(&transformed_rect, &point);
550 d2d_point_transform(&point, &render_target->transform, clip_rect->right * x_scale, clip_rect->top * y_scale);
551 d2d_rect_expand(&transformed_rect, &point);
552 d2d_point_transform(&point, &render_target->transform, clip_rect->right * x_scale, clip_rect->bottom * y_scale);
553 d2d_rect_expand(&transformed_rect, &point);
555 if (!d2d_clip_stack_push(&render_target->clip_stack, &transformed_rect))
556 WARN("Failed to push clip rect.\n");
559 static void STDMETHODCALLTYPE d2d_d3d_render_target_PopAxisAlignedClip(ID2D1RenderTarget *iface)
561 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
563 TRACE("iface %p.\n", iface);
565 d2d_clip_stack_pop(&render_target->clip_stack);
568 static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *iface, const D2D1_COLOR_F *color)
570 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
571 D3D10_SUBRESOURCE_DATA buffer_data;
572 D3D10_BUFFER_DESC buffer_desc;
573 unsigned int offset;
574 D3D10_VIEWPORT vp;
575 ID3D10Buffer *cb;
576 HRESULT hr;
578 TRACE("iface %p, color %p.\n", iface, color);
580 buffer_desc.ByteWidth = sizeof(*color);
581 buffer_desc.Usage = D3D10_USAGE_DEFAULT;
582 buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
583 buffer_desc.CPUAccessFlags = 0;
584 buffer_desc.MiscFlags = 0;
586 buffer_data.pSysMem = color;
587 buffer_data.SysMemPitch = 0;
588 buffer_data.SysMemSlicePitch = 0;
590 if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &cb)))
592 WARN("Failed to create constant buffer, hr %#x.\n", hr);
593 return;
596 vp.TopLeftX = 0;
597 vp.TopLeftY = 0;
598 vp.Width = render_target->pixel_size.width;
599 vp.Height = render_target->pixel_size.height;
600 vp.MinDepth = 0.0f;
601 vp.MaxDepth = 1.0f;
603 if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock)))
605 WARN("Failed to capture stateblock, hr %#x.\n", hr);
606 ID3D10Buffer_Release(cb);
607 return;
610 ID3D10Device_ClearState(render_target->device);
612 ID3D10Device_IASetInputLayout(render_target->device, render_target->clear_il);
613 ID3D10Device_IASetPrimitiveTopology(render_target->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
614 offset = 0;
615 ID3D10Device_IASetVertexBuffers(render_target->device, 0, 1,
616 &render_target->clear_vb, &render_target->clear_vb_stride, &offset);
617 ID3D10Device_VSSetShader(render_target->device, render_target->clear_vs);
618 ID3D10Device_PSSetConstantBuffers(render_target->device, 0, 1, &cb);
619 ID3D10Device_PSSetShader(render_target->device, render_target->clear_ps);
620 ID3D10Device_RSSetViewports(render_target->device, 1, &vp);
621 if (render_target->clip_stack.count)
623 const D2D1_RECT_F *clip_rect;
624 D3D10_RECT scissor_rect;
626 clip_rect = &render_target->clip_stack.stack[render_target->clip_stack.count - 1];
627 scissor_rect.left = clip_rect->left + 0.5f;
628 scissor_rect.top = clip_rect->top + 0.5f;
629 scissor_rect.right = clip_rect->right + 0.5f;
630 scissor_rect.bottom = clip_rect->bottom + 0.5f;
631 ID3D10Device_RSSetScissorRects(render_target->device, 1, &scissor_rect);
632 ID3D10Device_RSSetState(render_target->device, render_target->clear_rs);
634 ID3D10Device_OMSetRenderTargets(render_target->device, 1, &render_target->view, NULL);
636 ID3D10Device_Draw(render_target->device, 4, 0);
638 if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock)))
639 WARN("Failed to apply stateblock, hr %#x.\n", hr);
641 ID3D10Buffer_Release(cb);
644 static void STDMETHODCALLTYPE d2d_d3d_render_target_BeginDraw(ID2D1RenderTarget *iface)
646 TRACE("iface %p.\n", iface);
649 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_EndDraw(ID2D1RenderTarget *iface,
650 D2D1_TAG *tag1, D2D1_TAG *tag2)
652 TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
654 if (tag1)
655 *tag1 = 0;
656 if (tag2)
657 *tag2 = 0;
659 return S_OK;
662 static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelFormat(ID2D1RenderTarget *iface,
663 D2D1_PIXEL_FORMAT *format)
665 FIXME("iface %p, format %p stub!\n", iface, format);
667 format->format = DXGI_FORMAT_UNKNOWN;
668 format->alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
669 return format;
672 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetDpi(ID2D1RenderTarget *iface, float dpi_x, float dpi_y)
674 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
676 TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y);
678 if (dpi_x == 0.0f && dpi_y == 0.0f)
680 dpi_x = 96.0f;
681 dpi_y = 96.0f;
684 render_target->dpi_x = dpi_x;
685 render_target->dpi_y = dpi_y;
688 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *iface, float *dpi_x, float *dpi_y)
690 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
692 TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y);
694 *dpi_x = render_target->dpi_x;
695 *dpi_y = render_target->dpi_y;
698 static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface, D2D1_SIZE_F *size)
700 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
702 TRACE("iface %p, size %p.\n", iface, size);
704 size->width = render_target->pixel_size.width / (render_target->dpi_x / 96.0f);
705 size->height = render_target->pixel_size.height / (render_target->dpi_y / 96.0f);
706 return size;
709 static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelSize(ID2D1RenderTarget *iface,
710 D2D1_SIZE_U *pixel_size)
712 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
714 TRACE("iface %p, pixel_size %p.\n", iface, pixel_size);
716 *pixel_size = render_target->pixel_size;
717 return pixel_size;
720 static UINT32 STDMETHODCALLTYPE d2d_d3d_render_target_GetMaximumBitmapSize(ID2D1RenderTarget *iface)
722 FIXME("iface %p stub!\n", iface);
724 return 0;
727 static BOOL STDMETHODCALLTYPE d2d_d3d_render_target_IsSupported(ID2D1RenderTarget *iface,
728 const D2D1_RENDER_TARGET_PROPERTIES *desc)
730 FIXME("iface %p, desc %p stub!\n", iface, desc);
732 return FALSE;
735 static const struct ID2D1RenderTargetVtbl d2d_d3d_render_target_vtbl =
737 d2d_d3d_render_target_QueryInterface,
738 d2d_d3d_render_target_AddRef,
739 d2d_d3d_render_target_Release,
740 d2d_d3d_render_target_GetFactory,
741 d2d_d3d_render_target_CreateBitmap,
742 d2d_d3d_render_target_CreateBitmapFromWicBitmap,
743 d2d_d3d_render_target_CreateSharedBitmap,
744 d2d_d3d_render_target_CreateBitmapBrush,
745 d2d_d3d_render_target_CreateSolidColorBrush,
746 d2d_d3d_render_target_CreateGradientStopCollection,
747 d2d_d3d_render_target_CreateLinearGradientBrush,
748 d2d_d3d_render_target_CreateRadialGradientBrush,
749 d2d_d3d_render_target_CreateCompatibleRenderTarget,
750 d2d_d3d_render_target_CreateLayer,
751 d2d_d3d_render_target_CreateMesh,
752 d2d_d3d_render_target_DrawLine,
753 d2d_d3d_render_target_DrawRectangle,
754 d2d_d3d_render_target_FillRectangle,
755 d2d_d3d_render_target_DrawRoundedRectangle,
756 d2d_d3d_render_target_FillRoundedRectangle,
757 d2d_d3d_render_target_DrawEllipse,
758 d2d_d3d_render_target_FillEllipse,
759 d2d_d3d_render_target_DrawGeometry,
760 d2d_d3d_render_target_FillGeometry,
761 d2d_d3d_render_target_FillMesh,
762 d2d_d3d_render_target_FillOpacityMask,
763 d2d_d3d_render_target_DrawBitmap,
764 d2d_d3d_render_target_DrawText,
765 d2d_d3d_render_target_DrawTextLayout,
766 d2d_d3d_render_target_DrawGlyphRun,
767 d2d_d3d_render_target_SetTransform,
768 d2d_d3d_render_target_GetTransform,
769 d2d_d3d_render_target_SetAntialiasMode,
770 d2d_d3d_render_target_GetAntialiasMode,
771 d2d_d3d_render_target_SetTextAntialiasMode,
772 d2d_d3d_render_target_GetTextAntialiasMode,
773 d2d_d3d_render_target_SetTextRenderingParams,
774 d2d_d3d_render_target_GetTextRenderingParams,
775 d2d_d3d_render_target_SetTags,
776 d2d_d3d_render_target_GetTags,
777 d2d_d3d_render_target_PushLayer,
778 d2d_d3d_render_target_PopLayer,
779 d2d_d3d_render_target_Flush,
780 d2d_d3d_render_target_SaveDrawingState,
781 d2d_d3d_render_target_RestoreDrawingState,
782 d2d_d3d_render_target_PushAxisAlignedClip,
783 d2d_d3d_render_target_PopAxisAlignedClip,
784 d2d_d3d_render_target_Clear,
785 d2d_d3d_render_target_BeginDraw,
786 d2d_d3d_render_target_EndDraw,
787 d2d_d3d_render_target_GetPixelFormat,
788 d2d_d3d_render_target_SetDpi,
789 d2d_d3d_render_target_GetDpi,
790 d2d_d3d_render_target_GetSize,
791 d2d_d3d_render_target_GetPixelSize,
792 d2d_d3d_render_target_GetMaximumBitmapSize,
793 d2d_d3d_render_target_IsSupported,
796 HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
797 IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
799 D3D10_SUBRESOURCE_DATA buffer_data;
800 D3D10_STATE_BLOCK_MASK state_mask;
801 DXGI_SURFACE_DESC surface_desc;
802 D3D10_RASTERIZER_DESC rs_desc;
803 D3D10_BUFFER_DESC buffer_desc;
804 ID3D10Resource *resource;
805 HRESULT hr;
807 static const D3D10_INPUT_ELEMENT_DESC clear_il_desc[] =
809 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
811 static const DWORD clear_vs_code[] =
813 /* float4 main(float4 position : POSITION) : SV_POSITION
815 * return position;
816 * } */
817 0x43425844, 0x1fa8c27f, 0x52d2f21d, 0xc196fdb7, 0x376f283a, 0x00000001, 0x000001b4, 0x00000005,
818 0x00000034, 0x0000008c, 0x000000c0, 0x000000f4, 0x00000138, 0x46454452, 0x00000050, 0x00000000,
819 0x00000000, 0x00000000, 0x0000001c, 0xfffe0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
820 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e,
821 0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
822 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
823 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
824 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
825 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
826 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074,
827 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
828 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
829 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
830 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
832 static const DWORD clear_ps_code[] =
834 /* float4 color;
836 * float4 main(float4 position : SV_POSITION) : SV_Target
838 * return color;
839 * } */
840 0x43425844, 0xecd3cc9d, 0x0025bc77, 0x7a333165, 0x5b04c7e4, 0x00000001, 0x0000022c, 0x00000005,
841 0x00000034, 0x00000100, 0x00000134, 0x00000168, 0x000001b0, 0x46454452, 0x000000c4, 0x00000001,
842 0x00000048, 0x00000001, 0x0000001c, 0xffff0400, 0x00000100, 0x00000090, 0x0000003c, 0x00000000,
843 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x6f6c4724, 0x736c6162,
844 0xababab00, 0x0000003c, 0x00000001, 0x00000060, 0x00000010, 0x00000000, 0x00000000, 0x00000078,
845 0x00000000, 0x00000010, 0x00000002, 0x00000080, 0x00000000, 0x6f6c6f63, 0xabab0072, 0x00030001,
846 0x00040001, 0x00000000, 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53,
847 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
848 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
849 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001,
850 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
851 0x65677261, 0xabab0074, 0x52444853, 0x00000040, 0x00000040, 0x00000010, 0x04000059, 0x00208e46,
852 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x06000036, 0x001020f2, 0x00000000,
853 0x00208e46, 0x00000000, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
854 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
855 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
856 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
857 0x00000000, 0x00000000, 0x00000000,
859 static const struct
861 float x, y;
863 clear_quad[] =
865 {-1.0f, -1.0f},
866 {-1.0f, 1.0f},
867 { 1.0f, -1.0f},
868 { 1.0f, 1.0f},
870 static const D2D1_MATRIX_3X2_F identity =
872 1.0f, 0.0f,
873 0.0f, 1.0f,
874 0.0f, 0.0f,
877 FIXME("Ignoring render target properties.\n");
879 render_target->ID2D1RenderTarget_iface.lpVtbl = &d2d_d3d_render_target_vtbl;
880 render_target->refcount = 1;
882 if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
884 WARN("Failed to get device interface, hr %#x.\n", hr);
885 return hr;
888 if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
890 WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
891 goto err;
894 hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &render_target->view);
895 ID3D10Resource_Release(resource);
896 if (FAILED(hr))
898 WARN("Failed to create rendertarget view, hr %#x.\n", hr);
899 goto err;
902 if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask)))
904 WARN("Failed to create stateblock mask, hr %#x.\n", hr);
905 goto err;
908 if (FAILED(hr = D3D10CreateStateBlock(render_target->device, &state_mask, &render_target->stateblock)))
910 WARN("Failed to create stateblock, hr %#x.\n", hr);
911 goto err;
914 if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->device, clear_il_desc,
915 sizeof(clear_il_desc) / sizeof(*clear_il_desc), clear_vs_code, sizeof(clear_vs_code),
916 &render_target->clear_il)))
918 WARN("Failed to create clear input layout, hr %#x.\n", hr);
919 goto err;
922 buffer_desc.ByteWidth = sizeof(clear_quad);
923 buffer_desc.Usage = D3D10_USAGE_DEFAULT;
924 buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
925 buffer_desc.CPUAccessFlags = 0;
926 buffer_desc.MiscFlags = 0;
928 buffer_data.pSysMem = clear_quad;
929 buffer_data.SysMemPitch = 0;
930 buffer_data.SysMemSlicePitch = 0;
932 render_target->clear_vb_stride = sizeof(*clear_quad);
933 if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device,
934 &buffer_desc, &buffer_data, &render_target->clear_vb)))
936 WARN("Failed to create clear vertex buffer, hr %#x.\n", hr);
937 goto err;
940 if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->device,
941 clear_vs_code, sizeof(clear_vs_code), &render_target->clear_vs)))
943 WARN("Failed to create clear vertex shader, hr %#x.\n", hr);
944 goto err;
947 if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
948 clear_ps_code, sizeof(clear_ps_code), &render_target->clear_ps)))
950 WARN("Failed to create clear pixel shader, hr %#x.\n", hr);
951 goto err;
954 rs_desc.FillMode = D3D10_FILL_SOLID;
955 rs_desc.CullMode = D3D10_CULL_BACK;
956 rs_desc.FrontCounterClockwise = FALSE;
957 rs_desc.DepthBias = 0;
958 rs_desc.DepthBiasClamp = 0.0f;
959 rs_desc.SlopeScaledDepthBias = 0.0f;
960 rs_desc.DepthClipEnable = TRUE;
961 rs_desc.ScissorEnable = TRUE;
962 rs_desc.MultisampleEnable = FALSE;
963 rs_desc.AntialiasedLineEnable = FALSE;
964 if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->device, &rs_desc, &render_target->clear_rs)))
966 WARN("Failed to create clear rasterizer state, hr %#x.\n", hr);
967 goto err;
970 if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
972 WARN("Failed to get surface desc, hr %#x.\n", hr);
973 goto err;
976 render_target->pixel_size.width = surface_desc.Width;
977 render_target->pixel_size.height = surface_desc.Height;
978 render_target->transform = identity;
980 if (!d2d_clip_stack_init(&render_target->clip_stack))
982 WARN("Failed to initialize clip stack.\n");
983 hr = E_FAIL;
984 goto err;
987 render_target->dpi_x = desc->dpiX;
988 render_target->dpi_y = desc->dpiY;
990 if (render_target->dpi_x == 0.0f && render_target->dpi_y == 0.0f)
992 render_target->dpi_x = 96.0f;
993 render_target->dpi_y = 96.0f;
996 return S_OK;
998 err:
999 if (render_target->view)
1000 ID3D10RenderTargetView_Release(render_target->view);
1001 if (render_target->clear_rs)
1002 ID3D10RasterizerState_Release(render_target->clear_rs);
1003 if (render_target->clear_ps)
1004 ID3D10PixelShader_Release(render_target->clear_ps);
1005 if (render_target->clear_vs)
1006 ID3D10VertexShader_Release(render_target->clear_vs);
1007 if (render_target->clear_vb)
1008 ID3D10Buffer_Release(render_target->clear_vb);
1009 if (render_target->clear_il)
1010 ID3D10InputLayout_Release(render_target->clear_il);
1011 if (render_target->stateblock)
1012 render_target->stateblock->lpVtbl->Release(render_target->stateblock);
1013 if (render_target->device)
1014 ID3D10Device_Release(render_target->device);
1015 return hr;