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
{
D2D1_RECT_F *stack;
unsigned int stack_size;
unsigned int current;
D2D1_RECT_F clip_rect;
unsigned int size;
unsigned int count;
};
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;
}
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))))
return FALSE;
stack->stack_size = INITIAL_CLIP_STACK_SIZE;
stack->current = 0;
stack->clip_rect.left = 0.0f;
stack->clip_rect.top = 0.0f;
stack->clip_rect.right = w;
stack->clip_rect.bottom = h;
stack->size = INITIAL_CLIP_STACK_SIZE;
stack->count = 0;
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)
{
if (stack->current == stack->stack_size - 1)
D2D1_RECT_F r;
if (stack->count == stack->size)
{
D2D1_RECT_F *new_stack;
unsigned int new_size;
if (stack->stack_size > UINT_MAX / 2)
if (stack->size > UINT_MAX / 2)
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))))
return FALSE;
stack->stack = new_stack;
stack->stack_size = new_size;
stack->size = new_size;
}
stack->stack[stack->current++] = *rect;
d2d_rect_intersect(&stack->clip_rect, rect);
r = *rect;
if (stack->count)
d2d_rect_intersect(&r, &stack->stack[stack->count - 1]);
stack->stack[stack->count++] = r;
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->current)
if (!stack->count)
return;
--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]);
}
--stack->count;
}
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);
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)
@ -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);
D3D10_SUBRESOURCE_DATA buffer_data;
D3D10_BUFFER_DESC buffer_desc;
D3D10_RECT scissor_rect;
unsigned int offset;
D3D10_VIEWPORT vp;
ID3D10Buffer *cb;
@ -604,11 +590,6 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *ifa
vp.MinDepth = 0.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)))
{
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_PSSetShader(render_target->device, render_target->clear_ps);
ID3D10Device_RSSetViewports(render_target->device, 1, &vp);
ID3D10Device_RSSetScissorRects(render_target->device, 1, &scissor_rect);
ID3D10Device_RSSetState(render_target->device, render_target->clear_rs);
if (render_target->clip_stack.count)
{
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_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->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");
hr = E_FAIL;