d2d1: Simplify clip stack handling.

This commit is contained in:
Henri Verbeet 2014-09-15 11:03:33 +02:00 committed by Alexandre Julliard
parent 7d06f6ccb2
commit 240c454089
2 changed files with 33 additions and 42 deletions

View File

@ -28,9 +28,8 @@
struct d2d_clip_stack struct d2d_clip_stack
{ {
D2D1_RECT_F *stack; D2D1_RECT_F *stack;
unsigned int stack_size; unsigned int size;
unsigned int current; unsigned int count;
D2D1_RECT_F clip_rect;
}; };
struct d2d_d3d_render_target struct d2d_d3d_render_target

View File

@ -63,18 +63,13 @@ static void d2d_rect_set(D2D1_RECT_F *dst, float left, float top, float right, f
dst->bottom = bottom; dst->bottom = bottom;
} }
static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack, unsigned int w, unsigned int h) static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack)
{ {
if (!(stack->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack)))) if (!(stack->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack))))
return FALSE; return FALSE;
stack->stack_size = INITIAL_CLIP_STACK_SIZE; stack->size = INITIAL_CLIP_STACK_SIZE;
stack->current = 0; stack->count = 0;
stack->clip_rect.left = 0.0f;
stack->clip_rect.top = 0.0f;
stack->clip_rect.right = w;
stack->clip_rect.bottom = h;
return TRUE; return TRUE;
} }
@ -86,45 +81,37 @@ static void d2d_clip_stack_cleanup(struct d2d_clip_stack *stack)
static BOOL d2d_clip_stack_push(struct d2d_clip_stack *stack, const D2D1_RECT_F *rect) static BOOL d2d_clip_stack_push(struct d2d_clip_stack *stack, const D2D1_RECT_F *rect)
{ {
if (stack->current == stack->stack_size - 1) D2D1_RECT_F r;
if (stack->count == stack->size)
{ {
D2D1_RECT_F *new_stack; D2D1_RECT_F *new_stack;
unsigned int new_size; unsigned int new_size;
if (stack->stack_size > UINT_MAX / 2) if (stack->size > UINT_MAX / 2)
return FALSE; return FALSE;
new_size = stack->stack_size * 2; new_size = stack->size * 2;
if (!(new_stack = HeapReAlloc(GetProcessHeap(), 0, stack->stack, new_size * sizeof(*stack->stack)))) if (!(new_stack = HeapReAlloc(GetProcessHeap(), 0, stack->stack, new_size * sizeof(*stack->stack))))
return FALSE; return FALSE;
stack->stack = new_stack; stack->stack = new_stack;
stack->stack_size = new_size; stack->size = new_size;
} }
stack->stack[stack->current++] = *rect; r = *rect;
d2d_rect_intersect(&stack->clip_rect, rect); if (stack->count)
d2d_rect_intersect(&r, &stack->stack[stack->count - 1]);
stack->stack[stack->count++] = r;
return TRUE; return TRUE;
} }
static void d2d_clip_stack_pop(struct d2d_clip_stack *stack, unsigned int w, unsigned int h) static void d2d_clip_stack_pop(struct d2d_clip_stack *stack)
{ {
unsigned int i; if (!stack->count)
if (!stack->current)
return; return;
--stack->count;
--stack->current;
stack->clip_rect.left = 0.0f;
stack->clip_rect.top = 0.0f;
stack->clip_rect.right = w;
stack->clip_rect.bottom = h;
for (i = 0; i < stack->current; ++i)
{
d2d_rect_intersect(&stack->clip_rect, &stack->stack[i]);
}
} }
static inline struct d2d_d3d_render_target *impl_from_ID2D1RenderTarget(ID2D1RenderTarget *iface) static inline struct d2d_d3d_render_target *impl_from_ID2D1RenderTarget(ID2D1RenderTarget *iface)
@ -565,7 +552,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_PopAxisAlignedClip(ID2D1Rend
TRACE("iface %p.\n", iface); TRACE("iface %p.\n", iface);
d2d_clip_stack_pop(&render_target->clip_stack, render_target->pixel_size.width, render_target->pixel_size.height); d2d_clip_stack_pop(&render_target->clip_stack);
} }
static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *iface, const D2D1_COLOR_F *color) static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *iface, const D2D1_COLOR_F *color)
@ -573,7 +560,6 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *ifa
struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
D3D10_SUBRESOURCE_DATA buffer_data; D3D10_SUBRESOURCE_DATA buffer_data;
D3D10_BUFFER_DESC buffer_desc; D3D10_BUFFER_DESC buffer_desc;
D3D10_RECT scissor_rect;
unsigned int offset; unsigned int offset;
D3D10_VIEWPORT vp; D3D10_VIEWPORT vp;
ID3D10Buffer *cb; ID3D10Buffer *cb;
@ -604,11 +590,6 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *ifa
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
scissor_rect.left = render_target->clip_stack.clip_rect.left + 0.5f;
scissor_rect.top = render_target->clip_stack.clip_rect.top + 0.5f;
scissor_rect.right = render_target->clip_stack.clip_rect.right + 0.5f;
scissor_rect.bottom = render_target->clip_stack.clip_rect.bottom + 0.5f;
if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock))) if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock)))
{ {
WARN("Failed to capture stateblock, hr %#x.\n", hr); WARN("Failed to capture stateblock, hr %#x.\n", hr);
@ -627,8 +608,19 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *ifa
ID3D10Device_PSSetConstantBuffers(render_target->device, 0, 1, &cb); ID3D10Device_PSSetConstantBuffers(render_target->device, 0, 1, &cb);
ID3D10Device_PSSetShader(render_target->device, render_target->clear_ps); ID3D10Device_PSSetShader(render_target->device, render_target->clear_ps);
ID3D10Device_RSSetViewports(render_target->device, 1, &vp); ID3D10Device_RSSetViewports(render_target->device, 1, &vp);
ID3D10Device_RSSetScissorRects(render_target->device, 1, &scissor_rect); if (render_target->clip_stack.count)
ID3D10Device_RSSetState(render_target->device, render_target->clear_rs); {
const D2D1_RECT_F *clip_rect;
D3D10_RECT scissor_rect;
clip_rect = &render_target->clip_stack.stack[render_target->clip_stack.count - 1];
scissor_rect.left = clip_rect->left + 0.5f;
scissor_rect.top = clip_rect->top + 0.5f;
scissor_rect.right = clip_rect->right + 0.5f;
scissor_rect.bottom = clip_rect->bottom + 0.5f;
ID3D10Device_RSSetScissorRects(render_target->device, 1, &scissor_rect);
ID3D10Device_RSSetState(render_target->device, render_target->clear_rs);
}
ID3D10Device_OMSetRenderTargets(render_target->device, 1, &render_target->view, NULL); ID3D10Device_OMSetRenderTargets(render_target->device, 1, &render_target->view, NULL);
ID3D10Device_Draw(render_target->device, 4, 0); ID3D10Device_Draw(render_target->device, 4, 0);
@ -975,7 +967,7 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
render_target->pixel_size.height = surface_desc.Height; render_target->pixel_size.height = surface_desc.Height;
render_target->transform = identity; render_target->transform = identity;
if (!d2d_clip_stack_init(&render_target->clip_stack, surface_desc.Width, surface_desc.Height)) if (!d2d_clip_stack_init(&render_target->clip_stack))
{ {
WARN("Failed to initialize clip stack.\n"); WARN("Failed to initialize clip stack.\n");
hr = E_FAIL; hr = E_FAIL;