From: Henri Verbeet Subject: [PATCH 1/5] d2d1: Simplify clip stack handling. Message-Id: <1410771817-13660-1-git-send-email-hverbeet@codeweavers.com> Date: Mon, 15 Sep 2014 11:03:33 +0200 --- dlls/d2d1/d2d1_private.h | 5 ++-- dlls/d2d1/render_target.c | 70 ++++++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 586b978..ade194c 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -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 diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 268de41..4d69697 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -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; -- 1.7.10.4