d2d1: Simplify clip stack handling.
This commit is contained in:
parent
7d06f6ccb2
commit
240c454089
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue