Module: wine Branch: master Commit: 24814f8f4a13d231872b7bb1c3395165f0a6baa5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=24814f8f4a13d231872b7bb1c3...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Tue Sep 26 12:22:38 2017 +0200
d2d1: Create shader resource views for gradient stop collections.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/d2d1/brush.c | 68 +++++++++++++++++++++++++++++++++++++++++++++-- dlls/d2d1/d2d1_private.h | 3 ++- dlls/d2d1/render_target.c | 3 ++- 3 files changed, 70 insertions(+), 4 deletions(-)
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 18d9ddf..1fc00e9 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -68,6 +68,7 @@ static ULONG STDMETHODCALLTYPE d2d_gradient_Release(ID2D1GradientStopCollection if (!refcount) { HeapFree(GetProcessHeap(), 0, gradient->stops); + ID3D10ShaderResourceView_Release(gradient->view); ID2D1Factory_Release(gradient->factory); HeapFree(GetProcessHeap(), 0, gradient); } @@ -129,21 +130,84 @@ static const struct ID2D1GradientStopCollectionVtbl d2d_gradient_vtbl = d2d_gradient_GetExtendMode, };
-HRESULT d2d_gradient_create(ID2D1Factory *factory, const D2D1_GRADIENT_STOP *stops, +HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, struct d2d_gradient **gradient) { + D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc; + D3D10_SUBRESOURCE_DATA buffer_data; + ID3D10ShaderResourceView *view; + D3D10_BUFFER_DESC buffer_desc; + struct d2d_vec4 *data; + ID3D10Buffer *buffer; + unsigned int i; + HRESULT hr; + + if (!(data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2 * stop_count * sizeof(*data)))) + { + ERR("Failed to allocate data.\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < stop_count; ++i) + { + data[i * 2].x = stops[i].position; + data[i * 2 + 1].x = stops[i].color.r; + data[i * 2 + 1].y = stops[i].color.g; + data[i * 2 + 1].z = stops[i].color.b; + data[i * 2 + 1].w = stops[i].color.a; + } + + buffer_desc.ByteWidth = 2 * stop_count * sizeof(*data); + buffer_desc.Usage = D3D10_USAGE_DEFAULT; + buffer_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; + buffer_desc.CPUAccessFlags = 0; + buffer_desc.MiscFlags = 0; + + buffer_data.pSysMem = data; + buffer_data.SysMemPitch = 0; + buffer_data.SysMemSlicePitch = 0; + + hr = ID3D10Device_CreateBuffer(device, &buffer_desc, &buffer_data, &buffer); + HeapFree(GetProcessHeap(), 0, data); + if (FAILED(hr)) + { + ERR("Failed to create buffer, hr %#x.\n", hr); + return hr; + } + + srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + srv_desc.ViewDimension = D3D10_SRV_DIMENSION_BUFFER; + srv_desc.Buffer.ElementOffset = 0; + srv_desc.Buffer.ElementWidth = 2 * stop_count; + + hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)buffer, &srv_desc, &view); + ID3D10Buffer_Release(buffer); + if (FAILED(hr)) + { + ERR("Failed to create view, hr %#x.\n", hr); + return hr; + } + if (!(*gradient = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**gradient)))) + { + ID3D10ShaderResourceView_Release(view); return E_OUTOFMEMORY; + }
- FIXME("Ignoring gradient properties.\n"); + if (gamma != D2D1_GAMMA_2_2) + FIXME("Ignoring gamma %#x.\n", gamma); + if (extend_mode != D2D1_EXTEND_MODE_CLAMP) + FIXME("Ignoring extend mode %#x.\n", extend_mode);
(*gradient)->ID2D1GradientStopCollection_iface.lpVtbl = &d2d_gradient_vtbl; (*gradient)->refcount = 1; ID2D1Factory_AddRef((*gradient)->factory = factory); + (*gradient)->view = view;
(*gradient)->stop_count = stop_count; if (!((*gradient)->stops = HeapAlloc(GetProcessHeap(), 0, stop_count * sizeof(*stops)))) { + ID3D10ShaderResourceView_Release(view); HeapFree(GetProcessHeap(), 0, *gradient); return E_OUTOFMEMORY; } diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 2294568..efb504a 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -201,11 +201,12 @@ struct d2d_gradient LONG refcount;
ID2D1Factory *factory; + ID3D10ShaderResourceView *view; D2D1_GRADIENT_STOP *stops; UINT32 stop_count; };
-HRESULT d2d_gradient_create(ID2D1Factory *factory, const D2D1_GRADIENT_STOP *stops, +HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode, struct d2d_gradient **gradient) DECLSPEC_HIDDEN;
diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 0a23b31..98471cb 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -380,7 +380,8 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateGradientStopCollect TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n", iface, stops, stop_count, gamma, extend_mode, gradient);
- if (SUCCEEDED(hr = d2d_gradient_create(render_target->factory, stops, stop_count, gamma, extend_mode, &object))) + if (SUCCEEDED(hr = d2d_gradient_create(render_target->factory, render_target->device, + stops, stop_count, gamma, extend_mode, &object))) *gradient = &object->ID2D1GradientStopCollection_iface;
return hr;