d3d8: Get rid of the format switching code in d3d8_device_CopyRects().
[wine.git] / dlls / d2d1 / render_target.c
blob4a69fcee62bce8a3c98ec84b93f1e16ee6b75b90
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"
23 #include "wincodec.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d2d);
27 #define INITIAL_CLIP_STACK_SIZE 4
29 static void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y)
31 dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31;
32 dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32;
35 static void d2d_rect_expand(D2D1_RECT_F *dst, const D2D1_POINT_2F *point)
37 if (point->x < dst->left)
38 dst->left = point->x;
39 if (point->y < dst->top)
40 dst->top = point->y;
41 if (point->x > dst->right)
42 dst->right = point->x;
43 if (point->y > dst->bottom)
44 dst->bottom = point->y;
47 static void d2d_rect_intersect(D2D1_RECT_F *dst, const D2D1_RECT_F *src)
49 if (src->left > dst->left)
50 dst->left = src->left;
51 if (src->top > dst->top)
52 dst->top = src->top;
53 if (src->right < dst->right)
54 dst->right = src->right;
55 if (src->bottom < dst->bottom)
56 dst->bottom = src->bottom;
59 static void d2d_rect_set(D2D1_RECT_F *dst, float left, float top, float right, float bottom)
61 dst->left = left;
62 dst->top = top;
63 dst->right = right;
64 dst->bottom = bottom;
67 static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack)
69 if (!(stack->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack))))
70 return FALSE;
72 stack->size = INITIAL_CLIP_STACK_SIZE;
73 stack->count = 0;
75 return TRUE;
78 static void d2d_clip_stack_cleanup(struct d2d_clip_stack *stack)
80 HeapFree(GetProcessHeap(), 0, stack->stack);
83 static BOOL d2d_clip_stack_push(struct d2d_clip_stack *stack, const D2D1_RECT_F *rect)
85 D2D1_RECT_F r;
87 if (stack->count == stack->size)
89 D2D1_RECT_F *new_stack;
90 unsigned int new_size;
92 if (stack->size > UINT_MAX / 2)
93 return FALSE;
95 new_size = stack->size * 2;
96 if (!(new_stack = HeapReAlloc(GetProcessHeap(), 0, stack->stack, new_size * sizeof(*stack->stack))))
97 return FALSE;
99 stack->stack = new_stack;
100 stack->size = new_size;
103 r = *rect;
104 if (stack->count)
105 d2d_rect_intersect(&r, &stack->stack[stack->count - 1]);
106 stack->stack[stack->count++] = r;
108 return TRUE;
111 static void d2d_clip_stack_pop(struct d2d_clip_stack *stack)
113 if (!stack->count)
114 return;
115 --stack->count;
118 static inline struct d2d_d3d_render_target *impl_from_ID2D1RenderTarget(ID2D1RenderTarget *iface)
120 return CONTAINING_RECORD(iface, struct d2d_d3d_render_target, ID2D1RenderTarget_iface);
123 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_QueryInterface(ID2D1RenderTarget *iface, REFIID iid, void **out)
125 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
127 if (IsEqualGUID(iid, &IID_ID2D1RenderTarget)
128 || IsEqualGUID(iid, &IID_ID2D1Resource)
129 || IsEqualGUID(iid, &IID_IUnknown))
131 ID2D1RenderTarget_AddRef(iface);
132 *out = iface;
133 return S_OK;
136 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
138 *out = NULL;
139 return E_NOINTERFACE;
142 static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_AddRef(ID2D1RenderTarget *iface)
144 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
145 ULONG refcount = InterlockedIncrement(&render_target->refcount);
147 TRACE("%p increasing refcount to %u.\n", iface, refcount);
149 return refcount;
152 static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_Release(ID2D1RenderTarget *iface)
154 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
155 ULONG refcount = InterlockedDecrement(&render_target->refcount);
157 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
159 if (!refcount)
161 d2d_clip_stack_cleanup(&render_target->clip_stack);
162 ID3D10RenderTargetView_Release(render_target->view);
163 ID3D10RasterizerState_Release(render_target->clear_rs);
164 ID3D10PixelShader_Release(render_target->clear_ps);
165 ID3D10VertexShader_Release(render_target->clear_vs);
166 ID3D10Buffer_Release(render_target->clear_vb);
167 ID3D10InputLayout_Release(render_target->clear_il);
168 render_target->stateblock->lpVtbl->Release(render_target->stateblock);
169 ID3D10Device_Release(render_target->device);
170 HeapFree(GetProcessHeap(), 0, render_target);
173 return refcount;
176 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetFactory(ID2D1RenderTarget *iface, ID2D1Factory **factory)
178 FIXME("iface %p, factory %p stub!\n", iface, factory);
180 *factory = NULL;
183 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmap(ID2D1RenderTarget *iface,
184 D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
186 struct d2d_bitmap *object;
188 TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n",
189 iface, size.width, size.height, src_data, pitch, desc, bitmap);
191 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
192 return E_OUTOFMEMORY;
194 d2d_bitmap_init(object, size, src_data, pitch, desc);
196 TRACE("Created bitmap %p.\n", object);
197 *bitmap = &object->ID2D1Bitmap_iface;
199 return S_OK;
202 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapFromWicBitmap(ID2D1RenderTarget *iface,
203 IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
205 D2D1_BITMAP_PROPERTIES bitmap_desc;
206 unsigned int bpp, data_size;
207 D2D1_SIZE_U size;
208 WICRect rect;
209 UINT32 pitch;
210 HRESULT hr;
211 void *data;
213 TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n",
214 iface, bitmap_source, desc, bitmap);
216 if (FAILED(hr = IWICBitmapSource_GetSize(bitmap_source, &size.width, &size.height)))
218 WARN("Failed to get bitmap size, hr %#x.\n", hr);
219 return hr;
222 if (!desc)
224 bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
225 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
226 bitmap_desc.dpiX = 0.0f;
227 bitmap_desc.dpiY = 0.0f;
229 else
231 bitmap_desc = *desc;
234 if (bitmap_desc.pixelFormat.format == DXGI_FORMAT_UNKNOWN)
236 WICPixelFormatGUID wic_format;
238 if (FAILED(hr = IWICBitmapSource_GetPixelFormat(bitmap_source, &wic_format)))
240 WARN("Failed to get bitmap format, hr %#x.\n", hr);
241 return hr;
244 if (IsEqualGUID(&wic_format, &GUID_WICPixelFormat32bppPBGRA)
245 || IsEqualGUID(&wic_format, &GUID_WICPixelFormat32bppBGR))
247 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
249 else
251 WARN("Unsupported WIC bitmap format %s.\n", debugstr_guid(&wic_format));
252 return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
256 switch (bitmap_desc.pixelFormat.format)
258 case DXGI_FORMAT_B8G8R8A8_UNORM:
259 bpp = 4;
260 break;
262 default:
263 FIXME("Unhandled format %#x.\n", bitmap_desc.pixelFormat.format);
264 return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
267 pitch = ((bpp * size.width) + 15) & ~15;
268 data_size = pitch * size.height;
269 if (!(data = HeapAlloc(GetProcessHeap(), 0, data_size)))
270 return E_OUTOFMEMORY;
272 rect.X = 0;
273 rect.Y = 0;
274 rect.Width = size.width;
275 rect.Height = size.height;
276 if (FAILED(hr = IWICBitmapSource_CopyPixels(bitmap_source, &rect, pitch, data_size, data)))
278 WARN("Failed to copy bitmap pixels, hr %#x.\n", hr);
279 HeapFree(GetProcessHeap(), 0, data);
280 return hr;
283 hr = d2d_d3d_render_target_CreateBitmap(iface, size, data, pitch, &bitmap_desc, bitmap);
285 HeapFree(GetProcessHeap(), 0, data);
287 return hr;
290 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1RenderTarget *iface,
291 REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
293 FIXME("iface %p, iid %s, data %p, desc %p, bitmap %p stub!\n",
294 iface, debugstr_guid(iid), data, desc, bitmap);
296 return E_NOTIMPL;
299 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapBrush(ID2D1RenderTarget *iface,
300 ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc,
301 const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush)
303 FIXME("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p stub!\n",
304 iface, bitmap, bitmap_brush_desc, brush_desc, brush);
306 return E_NOTIMPL;
309 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSolidColorBrush(ID2D1RenderTarget *iface,
310 const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush)
312 struct d2d_brush *object;
314 TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush);
316 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
317 return E_OUTOFMEMORY;
319 d2d_solid_color_brush_init(object, iface, color, desc);
321 TRACE("Created brush %p.\n", object);
322 *brush = (ID2D1SolidColorBrush *)&object->ID2D1Brush_iface;
324 return S_OK;
327 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateGradientStopCollection(ID2D1RenderTarget *iface,
328 const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode,
329 ID2D1GradientStopCollection **gradient)
331 struct d2d_gradient *object;
333 TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n",
334 iface, stops, stop_count, gamma, extend_mode, gradient);
336 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
337 return E_OUTOFMEMORY;
339 d2d_gradient_init(object, iface, stops, stop_count, gamma, extend_mode);
341 TRACE("Created gradient %p.\n", object);
342 *gradient = &object->ID2D1GradientStopCollection_iface;
344 return S_OK;
347 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLinearGradientBrush(ID2D1RenderTarget *iface,
348 const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
349 ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush)
351 struct d2d_brush *object;
353 TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
354 iface, gradient_brush_desc, brush_desc, gradient, brush);
356 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
357 return E_OUTOFMEMORY;
359 d2d_linear_gradient_brush_init(object, iface, gradient_brush_desc, brush_desc, gradient);
361 TRACE("Created brush %p.\n", object);
362 *brush = (ID2D1LinearGradientBrush *)&object->ID2D1Brush_iface;
364 return S_OK;
367 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateRadialGradientBrush(ID2D1RenderTarget *iface,
368 const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
369 ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush)
371 FIXME("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p stub!\n",
372 iface, gradient_brush_desc, brush_desc, gradient, brush);
374 return E_NOTIMPL;
377 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateCompatibleRenderTarget(ID2D1RenderTarget *iface,
378 const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format,
379 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target)
381 FIXME("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p stub!\n",
382 iface, size, pixel_size, format, options, render_target);
384 return E_NOTIMPL;
387 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLayer(ID2D1RenderTarget *iface,
388 const D2D1_SIZE_F *size, ID2D1Layer **layer)
390 FIXME("iface %p, size %p, layer %p stub!\n", iface, size, layer);
392 return E_NOTIMPL;
395 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateMesh(ID2D1RenderTarget *iface, ID2D1Mesh **mesh)
397 struct d2d_mesh *object;
399 TRACE("iface %p, mesh %p.\n", iface, mesh);
401 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
402 return E_OUTOFMEMORY;
404 d2d_mesh_init(object);
406 TRACE("Created mesh %p.\n", object);
407 *mesh = &object->ID2D1Mesh_iface;
409 return S_OK;
412 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawLine(ID2D1RenderTarget *iface,
413 D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
415 FIXME("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
416 iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style);
419 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRectangle(ID2D1RenderTarget *iface,
420 const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
422 FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
423 iface, rect, brush, stroke_width, stroke_style);
426 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTarget *iface,
427 const D2D1_RECT_F *rect, ID2D1Brush *brush)
429 FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
432 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRoundedRectangle(ID2D1RenderTarget *iface,
433 const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
435 FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
436 iface, rect, brush, stroke_width, stroke_style);
439 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRoundedRectangle(ID2D1RenderTarget *iface,
440 const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush)
442 FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
445 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawEllipse(ID2D1RenderTarget *iface,
446 const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
448 FIXME("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
449 iface, ellipse, brush, stroke_width, stroke_style);
452 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillEllipse(ID2D1RenderTarget *iface,
453 const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush)
455 FIXME("iface %p, ellipse %p, brush %p stub!\n", iface, ellipse, brush);
458 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGeometry(ID2D1RenderTarget *iface,
459 ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
461 FIXME("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
462 iface, geometry, brush, stroke_width, stroke_style);
465 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarget *iface,
466 ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush)
468 FIXME("iface %p, geometry %p, brush %p, opacity_brush %p stub!\n", iface, geometry, brush, opacity_brush);
471 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillMesh(ID2D1RenderTarget *iface,
472 ID2D1Mesh *mesh, ID2D1Brush *brush)
474 FIXME("iface %p, mesh %p, brush %p stub!\n", iface, mesh, brush);
477 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillOpacityMask(ID2D1RenderTarget *iface,
478 ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content,
479 const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect)
481 FIXME("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p stub!\n",
482 iface, mask, brush, content, dst_rect, src_rect);
485 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawBitmap(ID2D1RenderTarget *iface,
486 ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity,
487 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect)
489 FIXME("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p stub!\n",
490 iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect);
493 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawText(ID2D1RenderTarget *iface,
494 const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect,
495 ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode)
497 FIXME("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, "
498 "brush %p, options %#x, measuring_mode %#x stub!\n",
499 iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect,
500 brush, options, measuring_mode);
503 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawTextLayout(ID2D1RenderTarget *iface,
504 D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options)
506 FIXME("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x stub!\n",
507 iface, origin.x, origin.y, layout, brush, options);
510 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarget *iface,
511 D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
512 DWRITE_MEASURING_MODE measuring_mode)
514 FIXME("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x stub!\n",
515 iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode);
518 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTransform(ID2D1RenderTarget *iface,
519 const D2D1_MATRIX_3X2_F *transform)
521 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
523 TRACE("iface %p, transform %p.\n", iface, transform);
525 render_target->transform = *transform;
528 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTransform(ID2D1RenderTarget *iface,
529 D2D1_MATRIX_3X2_F *transform)
531 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
533 TRACE("iface %p, transform %p.\n", iface, transform);
535 *transform = render_target->transform;
538 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetAntialiasMode(ID2D1RenderTarget *iface,
539 D2D1_ANTIALIAS_MODE antialias_mode)
541 FIXME("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
544 static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetAntialiasMode(ID2D1RenderTarget *iface)
546 FIXME("iface %p stub!\n", iface);
548 return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
551 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextAntialiasMode(ID2D1RenderTarget *iface,
552 D2D1_TEXT_ANTIALIAS_MODE antialias_mode)
554 FIXME("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
557 static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetTextAntialiasMode(ID2D1RenderTarget *iface)
559 FIXME("iface %p stub!\n", iface);
561 return D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
564 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextRenderingParams(ID2D1RenderTarget *iface,
565 IDWriteRenderingParams *text_rendering_params)
567 FIXME("iface %p, text_rendering_params %p stub!\n", iface, text_rendering_params);
570 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTextRenderingParams(ID2D1RenderTarget *iface,
571 IDWriteRenderingParams **text_rendering_params)
573 FIXME("iface %p, text_rendering_params %p stub!\n", iface, text_rendering_params);
575 *text_rendering_params = NULL;
578 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTags(ID2D1RenderTarget *iface, D2D1_TAG tag1, D2D1_TAG tag2)
580 FIXME("iface %p, tag1 %s, tag2 %s stub!\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2));
583 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTags(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
585 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
587 *tag1 = 0;
588 *tag2 = 0;
591 static void STDMETHODCALLTYPE d2d_d3d_render_target_PushLayer(ID2D1RenderTarget *iface,
592 const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer)
594 FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer);
597 static void STDMETHODCALLTYPE d2d_d3d_render_target_PopLayer(ID2D1RenderTarget *iface)
599 FIXME("iface %p stub!\n", iface);
602 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_Flush(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
604 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
606 return E_NOTIMPL;
609 static void STDMETHODCALLTYPE d2d_d3d_render_target_SaveDrawingState(ID2D1RenderTarget *iface,
610 ID2D1DrawingStateBlock *state_block)
612 FIXME("iface %p, state_block %p stub!\n", iface, state_block);
615 static void STDMETHODCALLTYPE d2d_d3d_render_target_RestoreDrawingState(ID2D1RenderTarget *iface,
616 ID2D1DrawingStateBlock *state_block)
618 FIXME("iface %p, state_block %p stub!\n", iface, state_block);
621 static void STDMETHODCALLTYPE d2d_d3d_render_target_PushAxisAlignedClip(ID2D1RenderTarget *iface,
622 const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode)
624 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
625 D2D1_RECT_F transformed_rect;
626 float x_scale, y_scale;
627 D2D1_POINT_2F point;
629 TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode);
631 if (antialias_mode != D2D1_ANTIALIAS_MODE_ALIASED)
632 FIXME("Ignoring antialias_mode %#x.\n", antialias_mode);
634 x_scale = render_target->dpi_x / 96.0f;
635 y_scale = render_target->dpi_y / 96.0f;
636 d2d_point_transform(&point, &render_target->transform, clip_rect->left * x_scale, clip_rect->top * y_scale);
637 d2d_rect_set(&transformed_rect, point.x, point.y, point.x, point.y);
638 d2d_point_transform(&point, &render_target->transform, clip_rect->left * x_scale, clip_rect->bottom * y_scale);
639 d2d_rect_expand(&transformed_rect, &point);
640 d2d_point_transform(&point, &render_target->transform, clip_rect->right * x_scale, clip_rect->top * y_scale);
641 d2d_rect_expand(&transformed_rect, &point);
642 d2d_point_transform(&point, &render_target->transform, clip_rect->right * x_scale, clip_rect->bottom * y_scale);
643 d2d_rect_expand(&transformed_rect, &point);
645 if (!d2d_clip_stack_push(&render_target->clip_stack, &transformed_rect))
646 WARN("Failed to push clip rect.\n");
649 static void STDMETHODCALLTYPE d2d_d3d_render_target_PopAxisAlignedClip(ID2D1RenderTarget *iface)
651 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
653 TRACE("iface %p.\n", iface);
655 d2d_clip_stack_pop(&render_target->clip_stack);
658 static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *iface, const D2D1_COLOR_F *color)
660 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
661 D3D10_SUBRESOURCE_DATA buffer_data;
662 D3D10_BUFFER_DESC buffer_desc;
663 unsigned int offset;
664 D3D10_VIEWPORT vp;
665 ID3D10Buffer *cb;
666 HRESULT hr;
668 TRACE("iface %p, color %p.\n", iface, color);
670 buffer_desc.ByteWidth = sizeof(*color);
671 buffer_desc.Usage = D3D10_USAGE_DEFAULT;
672 buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
673 buffer_desc.CPUAccessFlags = 0;
674 buffer_desc.MiscFlags = 0;
676 buffer_data.pSysMem = color;
677 buffer_data.SysMemPitch = 0;
678 buffer_data.SysMemSlicePitch = 0;
680 if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &cb)))
682 WARN("Failed to create constant buffer, hr %#x.\n", hr);
683 return;
686 vp.TopLeftX = 0;
687 vp.TopLeftY = 0;
688 vp.Width = render_target->pixel_size.width;
689 vp.Height = render_target->pixel_size.height;
690 vp.MinDepth = 0.0f;
691 vp.MaxDepth = 1.0f;
693 if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock)))
695 WARN("Failed to capture stateblock, hr %#x.\n", hr);
696 ID3D10Buffer_Release(cb);
697 return;
700 ID3D10Device_ClearState(render_target->device);
702 ID3D10Device_IASetInputLayout(render_target->device, render_target->clear_il);
703 ID3D10Device_IASetPrimitiveTopology(render_target->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
704 offset = 0;
705 ID3D10Device_IASetVertexBuffers(render_target->device, 0, 1,
706 &render_target->clear_vb, &render_target->clear_vb_stride, &offset);
707 ID3D10Device_VSSetShader(render_target->device, render_target->clear_vs);
708 ID3D10Device_PSSetConstantBuffers(render_target->device, 0, 1, &cb);
709 ID3D10Device_PSSetShader(render_target->device, render_target->clear_ps);
710 ID3D10Device_RSSetViewports(render_target->device, 1, &vp);
711 if (render_target->clip_stack.count)
713 const D2D1_RECT_F *clip_rect;
714 D3D10_RECT scissor_rect;
716 clip_rect = &render_target->clip_stack.stack[render_target->clip_stack.count - 1];
717 scissor_rect.left = clip_rect->left + 0.5f;
718 scissor_rect.top = clip_rect->top + 0.5f;
719 scissor_rect.right = clip_rect->right + 0.5f;
720 scissor_rect.bottom = clip_rect->bottom + 0.5f;
721 ID3D10Device_RSSetScissorRects(render_target->device, 1, &scissor_rect);
722 ID3D10Device_RSSetState(render_target->device, render_target->clear_rs);
724 ID3D10Device_OMSetRenderTargets(render_target->device, 1, &render_target->view, NULL);
726 ID3D10Device_Draw(render_target->device, 4, 0);
728 if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock)))
729 WARN("Failed to apply stateblock, hr %#x.\n", hr);
731 ID3D10Buffer_Release(cb);
734 static void STDMETHODCALLTYPE d2d_d3d_render_target_BeginDraw(ID2D1RenderTarget *iface)
736 TRACE("iface %p.\n", iface);
739 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_EndDraw(ID2D1RenderTarget *iface,
740 D2D1_TAG *tag1, D2D1_TAG *tag2)
742 TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
744 if (tag1)
745 *tag1 = 0;
746 if (tag2)
747 *tag2 = 0;
749 return S_OK;
752 static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelFormat(ID2D1RenderTarget *iface,
753 D2D1_PIXEL_FORMAT *format)
755 FIXME("iface %p, format %p stub!\n", iface, format);
757 format->format = DXGI_FORMAT_UNKNOWN;
758 format->alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
759 return format;
762 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetDpi(ID2D1RenderTarget *iface, float dpi_x, float dpi_y)
764 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
766 TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y);
768 if (dpi_x == 0.0f && dpi_y == 0.0f)
770 dpi_x = 96.0f;
771 dpi_y = 96.0f;
774 render_target->dpi_x = dpi_x;
775 render_target->dpi_y = dpi_y;
778 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *iface, float *dpi_x, float *dpi_y)
780 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
782 TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y);
784 *dpi_x = render_target->dpi_x;
785 *dpi_y = render_target->dpi_y;
788 static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface, D2D1_SIZE_F *size)
790 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
792 TRACE("iface %p, size %p.\n", iface, size);
794 size->width = render_target->pixel_size.width / (render_target->dpi_x / 96.0f);
795 size->height = render_target->pixel_size.height / (render_target->dpi_y / 96.0f);
796 return size;
799 static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelSize(ID2D1RenderTarget *iface,
800 D2D1_SIZE_U *pixel_size)
802 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
804 TRACE("iface %p, pixel_size %p.\n", iface, pixel_size);
806 *pixel_size = render_target->pixel_size;
807 return pixel_size;
810 static UINT32 STDMETHODCALLTYPE d2d_d3d_render_target_GetMaximumBitmapSize(ID2D1RenderTarget *iface)
812 FIXME("iface %p stub!\n", iface);
814 return 0;
817 static BOOL STDMETHODCALLTYPE d2d_d3d_render_target_IsSupported(ID2D1RenderTarget *iface,
818 const D2D1_RENDER_TARGET_PROPERTIES *desc)
820 FIXME("iface %p, desc %p stub!\n", iface, desc);
822 return FALSE;
825 static const struct ID2D1RenderTargetVtbl d2d_d3d_render_target_vtbl =
827 d2d_d3d_render_target_QueryInterface,
828 d2d_d3d_render_target_AddRef,
829 d2d_d3d_render_target_Release,
830 d2d_d3d_render_target_GetFactory,
831 d2d_d3d_render_target_CreateBitmap,
832 d2d_d3d_render_target_CreateBitmapFromWicBitmap,
833 d2d_d3d_render_target_CreateSharedBitmap,
834 d2d_d3d_render_target_CreateBitmapBrush,
835 d2d_d3d_render_target_CreateSolidColorBrush,
836 d2d_d3d_render_target_CreateGradientStopCollection,
837 d2d_d3d_render_target_CreateLinearGradientBrush,
838 d2d_d3d_render_target_CreateRadialGradientBrush,
839 d2d_d3d_render_target_CreateCompatibleRenderTarget,
840 d2d_d3d_render_target_CreateLayer,
841 d2d_d3d_render_target_CreateMesh,
842 d2d_d3d_render_target_DrawLine,
843 d2d_d3d_render_target_DrawRectangle,
844 d2d_d3d_render_target_FillRectangle,
845 d2d_d3d_render_target_DrawRoundedRectangle,
846 d2d_d3d_render_target_FillRoundedRectangle,
847 d2d_d3d_render_target_DrawEllipse,
848 d2d_d3d_render_target_FillEllipse,
849 d2d_d3d_render_target_DrawGeometry,
850 d2d_d3d_render_target_FillGeometry,
851 d2d_d3d_render_target_FillMesh,
852 d2d_d3d_render_target_FillOpacityMask,
853 d2d_d3d_render_target_DrawBitmap,
854 d2d_d3d_render_target_DrawText,
855 d2d_d3d_render_target_DrawTextLayout,
856 d2d_d3d_render_target_DrawGlyphRun,
857 d2d_d3d_render_target_SetTransform,
858 d2d_d3d_render_target_GetTransform,
859 d2d_d3d_render_target_SetAntialiasMode,
860 d2d_d3d_render_target_GetAntialiasMode,
861 d2d_d3d_render_target_SetTextAntialiasMode,
862 d2d_d3d_render_target_GetTextAntialiasMode,
863 d2d_d3d_render_target_SetTextRenderingParams,
864 d2d_d3d_render_target_GetTextRenderingParams,
865 d2d_d3d_render_target_SetTags,
866 d2d_d3d_render_target_GetTags,
867 d2d_d3d_render_target_PushLayer,
868 d2d_d3d_render_target_PopLayer,
869 d2d_d3d_render_target_Flush,
870 d2d_d3d_render_target_SaveDrawingState,
871 d2d_d3d_render_target_RestoreDrawingState,
872 d2d_d3d_render_target_PushAxisAlignedClip,
873 d2d_d3d_render_target_PopAxisAlignedClip,
874 d2d_d3d_render_target_Clear,
875 d2d_d3d_render_target_BeginDraw,
876 d2d_d3d_render_target_EndDraw,
877 d2d_d3d_render_target_GetPixelFormat,
878 d2d_d3d_render_target_SetDpi,
879 d2d_d3d_render_target_GetDpi,
880 d2d_d3d_render_target_GetSize,
881 d2d_d3d_render_target_GetPixelSize,
882 d2d_d3d_render_target_GetMaximumBitmapSize,
883 d2d_d3d_render_target_IsSupported,
886 HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
887 IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
889 D3D10_SUBRESOURCE_DATA buffer_data;
890 D3D10_STATE_BLOCK_MASK state_mask;
891 DXGI_SURFACE_DESC surface_desc;
892 D3D10_RASTERIZER_DESC rs_desc;
893 D3D10_BUFFER_DESC buffer_desc;
894 ID3D10Resource *resource;
895 HRESULT hr;
897 static const D3D10_INPUT_ELEMENT_DESC clear_il_desc[] =
899 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
901 static const DWORD clear_vs_code[] =
903 /* float4 main(float4 position : POSITION) : SV_POSITION
905 * return position;
906 * } */
907 0x43425844, 0x1fa8c27f, 0x52d2f21d, 0xc196fdb7, 0x376f283a, 0x00000001, 0x000001b4, 0x00000005,
908 0x00000034, 0x0000008c, 0x000000c0, 0x000000f4, 0x00000138, 0x46454452, 0x00000050, 0x00000000,
909 0x00000000, 0x00000000, 0x0000001c, 0xfffe0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
910 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e,
911 0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
912 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
913 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
914 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
915 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
916 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074,
917 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
918 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
919 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
920 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
922 static const DWORD clear_ps_code[] =
924 /* float4 color;
926 * float4 main(float4 position : SV_POSITION) : SV_Target
928 * return color;
929 * } */
930 0x43425844, 0xecd3cc9d, 0x0025bc77, 0x7a333165, 0x5b04c7e4, 0x00000001, 0x0000022c, 0x00000005,
931 0x00000034, 0x00000100, 0x00000134, 0x00000168, 0x000001b0, 0x46454452, 0x000000c4, 0x00000001,
932 0x00000048, 0x00000001, 0x0000001c, 0xffff0400, 0x00000100, 0x00000090, 0x0000003c, 0x00000000,
933 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x6f6c4724, 0x736c6162,
934 0xababab00, 0x0000003c, 0x00000001, 0x00000060, 0x00000010, 0x00000000, 0x00000000, 0x00000078,
935 0x00000000, 0x00000010, 0x00000002, 0x00000080, 0x00000000, 0x6f6c6f63, 0xabab0072, 0x00030001,
936 0x00040001, 0x00000000, 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53,
937 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
938 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
939 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001,
940 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
941 0x65677261, 0xabab0074, 0x52444853, 0x00000040, 0x00000040, 0x00000010, 0x04000059, 0x00208e46,
942 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x06000036, 0x001020f2, 0x00000000,
943 0x00208e46, 0x00000000, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
944 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
945 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
946 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
947 0x00000000, 0x00000000, 0x00000000,
949 static const struct
951 float x, y;
953 clear_quad[] =
955 {-1.0f, -1.0f},
956 {-1.0f, 1.0f},
957 { 1.0f, -1.0f},
958 { 1.0f, 1.0f},
960 static const D2D1_MATRIX_3X2_F identity =
962 1.0f, 0.0f,
963 0.0f, 1.0f,
964 0.0f, 0.0f,
967 FIXME("Ignoring render target properties.\n");
969 render_target->ID2D1RenderTarget_iface.lpVtbl = &d2d_d3d_render_target_vtbl;
970 render_target->refcount = 1;
972 if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
974 WARN("Failed to get device interface, hr %#x.\n", hr);
975 return hr;
978 if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
980 WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
981 goto err;
984 hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &render_target->view);
985 ID3D10Resource_Release(resource);
986 if (FAILED(hr))
988 WARN("Failed to create rendertarget view, hr %#x.\n", hr);
989 goto err;
992 if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask)))
994 WARN("Failed to create stateblock mask, hr %#x.\n", hr);
995 goto err;
998 if (FAILED(hr = D3D10CreateStateBlock(render_target->device, &state_mask, &render_target->stateblock)))
1000 WARN("Failed to create stateblock, hr %#x.\n", hr);
1001 goto err;
1004 if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->device, clear_il_desc,
1005 sizeof(clear_il_desc) / sizeof(*clear_il_desc), clear_vs_code, sizeof(clear_vs_code),
1006 &render_target->clear_il)))
1008 WARN("Failed to create clear input layout, hr %#x.\n", hr);
1009 goto err;
1012 buffer_desc.ByteWidth = sizeof(clear_quad);
1013 buffer_desc.Usage = D3D10_USAGE_DEFAULT;
1014 buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
1015 buffer_desc.CPUAccessFlags = 0;
1016 buffer_desc.MiscFlags = 0;
1018 buffer_data.pSysMem = clear_quad;
1019 buffer_data.SysMemPitch = 0;
1020 buffer_data.SysMemSlicePitch = 0;
1022 render_target->clear_vb_stride = sizeof(*clear_quad);
1023 if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device,
1024 &buffer_desc, &buffer_data, &render_target->clear_vb)))
1026 WARN("Failed to create clear vertex buffer, hr %#x.\n", hr);
1027 goto err;
1030 if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->device,
1031 clear_vs_code, sizeof(clear_vs_code), &render_target->clear_vs)))
1033 WARN("Failed to create clear vertex shader, hr %#x.\n", hr);
1034 goto err;
1037 if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
1038 clear_ps_code, sizeof(clear_ps_code), &render_target->clear_ps)))
1040 WARN("Failed to create clear pixel shader, hr %#x.\n", hr);
1041 goto err;
1044 rs_desc.FillMode = D3D10_FILL_SOLID;
1045 rs_desc.CullMode = D3D10_CULL_BACK;
1046 rs_desc.FrontCounterClockwise = FALSE;
1047 rs_desc.DepthBias = 0;
1048 rs_desc.DepthBiasClamp = 0.0f;
1049 rs_desc.SlopeScaledDepthBias = 0.0f;
1050 rs_desc.DepthClipEnable = TRUE;
1051 rs_desc.ScissorEnable = TRUE;
1052 rs_desc.MultisampleEnable = FALSE;
1053 rs_desc.AntialiasedLineEnable = FALSE;
1054 if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->device, &rs_desc, &render_target->clear_rs)))
1056 WARN("Failed to create clear rasterizer state, hr %#x.\n", hr);
1057 goto err;
1060 if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
1062 WARN("Failed to get surface desc, hr %#x.\n", hr);
1063 goto err;
1066 render_target->pixel_size.width = surface_desc.Width;
1067 render_target->pixel_size.height = surface_desc.Height;
1068 render_target->transform = identity;
1070 if (!d2d_clip_stack_init(&render_target->clip_stack))
1072 WARN("Failed to initialize clip stack.\n");
1073 hr = E_FAIL;
1074 goto err;
1077 render_target->dpi_x = desc->dpiX;
1078 render_target->dpi_y = desc->dpiY;
1080 if (render_target->dpi_x == 0.0f && render_target->dpi_y == 0.0f)
1082 render_target->dpi_x = 96.0f;
1083 render_target->dpi_y = 96.0f;
1086 return S_OK;
1088 err:
1089 if (render_target->view)
1090 ID3D10RenderTargetView_Release(render_target->view);
1091 if (render_target->clear_rs)
1092 ID3D10RasterizerState_Release(render_target->clear_rs);
1093 if (render_target->clear_ps)
1094 ID3D10PixelShader_Release(render_target->clear_ps);
1095 if (render_target->clear_vs)
1096 ID3D10VertexShader_Release(render_target->clear_vs);
1097 if (render_target->clear_vb)
1098 ID3D10Buffer_Release(render_target->clear_vb);
1099 if (render_target->clear_il)
1100 ID3D10InputLayout_Release(render_target->clear_il);
1101 if (render_target->stateblock)
1102 render_target->stateblock->lpVtbl->Release(render_target->stateblock);
1103 if (render_target->device)
1104 ID3D10Device_Release(render_target->device);
1105 return hr;