[win32, surface] always resize surface to parent window's client area
This commit is contained in:
parent
985aed852a
commit
3816e85592
|
@ -161,6 +161,9 @@ int main()
|
|||
mg_set_color_rgba(0, 1, 1, 1);
|
||||
mg_clear();
|
||||
|
||||
mg_set_color_rgba(1, 0, 1, 1);
|
||||
mg_rectangle_fill(0, 0, 100, 100);
|
||||
|
||||
// head
|
||||
mg_set_color_rgba(1, 1, 0, 1);
|
||||
|
||||
|
|
|
@ -130,6 +130,10 @@ typedef struct mg_gl_canvas_backend
|
|||
mg_canvas_backend interface;
|
||||
mg_wgl_surface* surface;
|
||||
|
||||
int msaaCount;
|
||||
vec2 frameSize;
|
||||
|
||||
// gl stuff
|
||||
GLuint vao;
|
||||
|
||||
GLuint pathSetup;
|
||||
|
@ -155,17 +159,12 @@ typedef struct mg_gl_canvas_backend
|
|||
GLuint tileOpCountBuffer;
|
||||
GLuint screenTilesBuffer;
|
||||
GLuint rasterDispatchBuffer;
|
||||
|
||||
GLuint dummyVertexBuffer;
|
||||
|
||||
int msaaCount;
|
||||
vec2 frameSize;
|
||||
|
||||
//encoding context
|
||||
int pathCount;
|
||||
int eltCount;
|
||||
|
||||
/////////////////
|
||||
int pathBatchStart;
|
||||
int eltBatchStart;
|
||||
|
||||
|
@ -1201,10 +1200,28 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend,
|
|||
backend->eltBatchStart = backend->eltCount;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//TODO
|
||||
void mg_gl_canvas_resize(mg_gl_canvas_backend* backend, vec2 size);
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
void mg_gl_canvas_resize(mg_gl_canvas_backend* backend, vec2 size)
|
||||
{
|
||||
int tileSize = MG_GL_TILE_SIZE;
|
||||
int nTilesX = (int)(size.x + tileSize - 1)/tileSize;
|
||||
int nTilesY = (int)(size.y + tileSize - 1)/tileSize;
|
||||
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, nTilesX*nTilesY*sizeof(mg_gl_screen_tile), 0, GL_DYNAMIC_COPY);
|
||||
|
||||
if(backend->outTexture)
|
||||
{
|
||||
//NOTE: do we need to explicitly glDeleteTextures()?
|
||||
glDeleteTextures(1, &backend->outTexture);
|
||||
glGenTextures(1, &backend->outTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, backend->outTexture);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size.x, size.y);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
backend->frameSize = size;
|
||||
}
|
||||
|
||||
void mg_gl_canvas_render(mg_canvas_backend* interface,
|
||||
mg_color clearColor,
|
||||
|
@ -1224,23 +1241,29 @@ void mg_gl_canvas_render(mg_canvas_backend* interface,
|
|||
backend->bufferSync[backend->bufferIndex] = 0;
|
||||
}
|
||||
|
||||
//TODO update screen tiles buffer size
|
||||
//NOTE update screen tiles buffer size
|
||||
mg_wgl_surface* surface = backend->surface;
|
||||
mp_rect frame = surface->interface.getFrame((mg_surface_data*)surface);
|
||||
vec2 surfaceSize = surface->interface.getSize((mg_surface_data*)surface);
|
||||
vec2 contentsScaling = surface->interface.contentsScaling((mg_surface_data*)surface);
|
||||
//TODO support scaling in both axes
|
||||
//TODO support scaling in both axes?
|
||||
f32 scale = contentsScaling.x;
|
||||
|
||||
vec2 viewportSize = {frame.w * scale, frame.h * scale};
|
||||
vec2 viewportSize = {surfaceSize.x * scale, surfaceSize.y * scale};
|
||||
int tileSize = MG_GL_TILE_SIZE;
|
||||
int nTilesX = (int)(frame.w * scale + tileSize - 1)/tileSize;
|
||||
int nTilesY = (int)(frame.h * scale + tileSize - 1)/tileSize;
|
||||
int nTilesX = (int)(viewportSize.x + tileSize - 1)/tileSize;
|
||||
int nTilesY = (int)(viewportSize.y + tileSize - 1)/tileSize;
|
||||
|
||||
if(viewportSize.x != backend->frameSize.x || viewportSize.y != backend->frameSize.y)
|
||||
{
|
||||
//TODO: mg_gl_canvas_resize(backend, viewportSize);
|
||||
mg_gl_canvas_resize(backend, viewportSize);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//TODO: the surface's frame and the underlying window/view rect are not necessarily the same.
|
||||
// we should set the viewport to cover the whole surface's frame, so it might not start at (0, 0)
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
glViewport(0, 0, viewportSize.x, viewportSize.y);
|
||||
|
||||
//NOTE: clear screen and reset input buffer offsets
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
@ -1544,12 +1567,14 @@ mg_canvas_backend* gl_canvas_backend_create(mg_wgl_surface* surface)
|
|||
}
|
||||
|
||||
//NOTE: create out texture
|
||||
mp_rect frame = surface->interface.getFrame((mg_surface_data*)surface);
|
||||
vec2 size = surface->interface.getSize((mg_surface_data*)surface);
|
||||
vec2 scale = surface->interface.contentsScaling((mg_surface_data*)surface);
|
||||
|
||||
backend->frameSize = (vec2){size.x * scale.x, size.y * scale.y};
|
||||
|
||||
glGenTextures(1, &backend->outTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, backend->outTexture);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, frame.w*scale.x, frame.h*scale.y);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, backend->frameSize.x, backend->frameSize.y);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
@ -1611,8 +1636,8 @@ mg_canvas_backend* gl_canvas_backend_create(mg_wgl_surface* surface)
|
|||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY);
|
||||
|
||||
int tileSize = MG_GL_TILE_SIZE;
|
||||
int nTilesX = (int)(frame.w * scale.x + tileSize - 1)/tileSize;
|
||||
int nTilesY = (int)(frame.h * scale.y + tileSize - 1)/tileSize;
|
||||
int nTilesX = (int)(backend->frameSize.x + tileSize - 1)/tileSize;
|
||||
int nTilesY = (int)(backend->frameSize.y + tileSize - 1)/tileSize;
|
||||
|
||||
glGenBuffers(1, &backend->screenTilesBuffer);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesBuffer);
|
||||
|
|
|
@ -105,9 +105,8 @@ MP_API void mg_surface_present(mg_surface surface);
|
|||
MP_API void mg_surface_deselect(void);
|
||||
|
||||
MP_API void mg_surface_swap_interval(mg_surface surface, int swap);
|
||||
MP_API vec2 mg_surface_get_size(mg_surface surface);
|
||||
MP_API vec2 mg_surface_contents_scaling(mg_surface surface);
|
||||
MP_API mp_rect mg_surface_get_frame(mg_surface surface);
|
||||
MP_API void mg_surface_set_frame(mg_surface surface, mp_rect frame);
|
||||
MP_API bool mg_surface_get_hidden(mg_surface surface);
|
||||
MP_API void mg_surface_set_hidden(mg_surface surface, bool hidden);
|
||||
|
||||
|
|
|
@ -263,6 +263,18 @@ void mg_surface_swap_interval(mg_surface surface, int swap)
|
|||
}
|
||||
}
|
||||
|
||||
vec2 mg_surface_get_size(mg_surface surface)
|
||||
{
|
||||
DEBUG_ASSERT(__mgData.init);
|
||||
vec2 size = {0};
|
||||
mg_surface_data* surfaceData = mg_surface_data_from_handle(surface);
|
||||
if(surfaceData && surfaceData->getSize)
|
||||
{
|
||||
size = surfaceData->getSize(surfaceData);
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
|
||||
vec2 mg_surface_contents_scaling(mg_surface surface)
|
||||
{
|
||||
DEBUG_ASSERT(__mgData.init);
|
||||
|
@ -275,29 +287,6 @@ vec2 mg_surface_contents_scaling(mg_surface surface)
|
|||
return(scaling);
|
||||
}
|
||||
|
||||
|
||||
void mg_surface_set_frame(mg_surface surface, mp_rect frame)
|
||||
{
|
||||
DEBUG_ASSERT(__mgData.init);
|
||||
mg_surface_data* surfaceData = mg_surface_data_from_handle(surface);
|
||||
if(surfaceData && surfaceData->setFrame)
|
||||
{
|
||||
surfaceData->setFrame(surfaceData, frame);
|
||||
}
|
||||
}
|
||||
|
||||
mp_rect mg_surface_get_frame(mg_surface surface)
|
||||
{
|
||||
DEBUG_ASSERT(__mgData.init);
|
||||
mp_rect res = {0};
|
||||
mg_surface_data* surfaceData = mg_surface_data_from_handle(surface);
|
||||
if(surfaceData && surfaceData->getFrame)
|
||||
{
|
||||
res = surfaceData->getFrame(surfaceData);
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
void mg_surface_set_hidden(mg_surface surface, bool hidden)
|
||||
{
|
||||
DEBUG_ASSERT(__mgData.init);
|
||||
|
|
|
@ -26,9 +26,8 @@ typedef void (*mg_surface_prepare_proc)(mg_surface_data* surface);
|
|||
typedef void (*mg_surface_deselect_proc)(mg_surface_data* surface);
|
||||
typedef void (*mg_surface_present_proc)(mg_surface_data* surface);
|
||||
typedef void (*mg_surface_swap_interval_proc)(mg_surface_data* surface, int swap);
|
||||
typedef vec2 (*mg_surface_get_size_proc)(mg_surface_data* surface);
|
||||
typedef vec2 (*mg_surface_contents_scaling_proc)(mg_surface_data* surface);
|
||||
typedef mp_rect (*mg_surface_get_frame_proc)(mg_surface_data* surface);
|
||||
typedef void (*mg_surface_set_frame_proc)(mg_surface_data* surface, mp_rect frame);
|
||||
typedef bool (*mg_surface_get_hidden_proc)(mg_surface_data* surface);
|
||||
typedef void (*mg_surface_set_hidden_proc)(mg_surface_data* surface, bool hidden);
|
||||
typedef void* (*mg_surface_native_layer_proc)(mg_surface_data* surface);
|
||||
|
@ -45,9 +44,8 @@ typedef struct mg_surface_data
|
|||
mg_surface_present_proc present;
|
||||
mg_surface_deselect_proc deselect;
|
||||
mg_surface_swap_interval_proc swapInterval;
|
||||
mg_surface_get_size_proc getSize;
|
||||
mg_surface_contents_scaling_proc contentsScaling;
|
||||
mg_surface_get_frame_proc getFrame;
|
||||
mg_surface_set_frame_proc setFrame;
|
||||
mg_surface_get_hidden_proc getHidden;
|
||||
mg_surface_set_hidden_proc setHidden;
|
||||
mg_surface_native_layer_proc nativeLayer;
|
||||
|
@ -79,34 +77,6 @@ typedef struct mg_image_data
|
|||
|
||||
} mg_image_data;
|
||||
|
||||
typedef struct mg_vertex_layout
|
||||
{
|
||||
u32 maxVertexCount;
|
||||
u32 maxIndexCount;
|
||||
|
||||
char* posBuffer;
|
||||
u32 posStride;
|
||||
|
||||
char* cubicBuffer;
|
||||
u32 cubicStride;
|
||||
|
||||
char* shapeIndexBuffer;
|
||||
u32 shapeIndexStride;
|
||||
|
||||
char* colorBuffer;
|
||||
u32 colorStride;
|
||||
|
||||
char* clipBuffer;
|
||||
u32 clipStride;
|
||||
|
||||
char* uvTransformBuffer;
|
||||
u32 uvTransformStride;
|
||||
|
||||
char* indexBuffer;
|
||||
u32 indexStride;
|
||||
|
||||
} mg_vertex_layout;
|
||||
|
||||
typedef void (*mg_canvas_backend_destroy_proc)(mg_canvas_backend* backend);
|
||||
typedef void (*mg_canvas_backend_begin_proc)(mg_canvas_backend* backend, mg_color clearColor);
|
||||
typedef void (*mg_canvas_backend_end_proc)(mg_canvas_backend* backend);
|
||||
|
@ -133,8 +103,6 @@ typedef void (*mg_canvas_backend_render_proc)(mg_canvas_backend* backend,
|
|||
|
||||
typedef struct mg_canvas_backend
|
||||
{
|
||||
// mg_vertex_layout vertexLayout;
|
||||
|
||||
mg_canvas_backend_destroy_proc destroy;
|
||||
mg_canvas_backend_begin_proc begin;
|
||||
mg_canvas_backend_end_proc end;
|
||||
|
@ -144,7 +112,6 @@ typedef struct mg_canvas_backend
|
|||
mg_canvas_backend_image_destroy_proc imageDestroy;
|
||||
mg_canvas_backend_image_upload_region_proc imageUploadRegion;
|
||||
|
||||
|
||||
mg_canvas_backend_render_proc render;
|
||||
|
||||
} mg_canvas_backend;
|
||||
|
|
|
@ -247,39 +247,6 @@ static void process_wheel_event(mp_window_data* window, f32 x, f32 y)
|
|||
mp_queue_event(&event);
|
||||
}
|
||||
|
||||
void mg_win32_layer_set_frame(mp_layer* layer, mp_rect frame)
|
||||
{
|
||||
layer->userFrame = frame;
|
||||
|
||||
HWND parent = GetParent(layer->hWnd);
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(parent, &clientRect);
|
||||
POINT point = {0};
|
||||
ClientToScreen(layer->hWnd, &point);
|
||||
|
||||
u32 dpi = GetDpiForWindow(layer->hWnd);
|
||||
vec2 scale = (vec2){(float)dpi/96., (float)dpi/96.};
|
||||
|
||||
int parentWidth = (clientRect.right - clientRect.left)/scale.x;
|
||||
int parentHeight = (clientRect.bottom - clientRect.top)/scale.y;
|
||||
|
||||
int minX = Clamp(frame.x, 0, parentWidth);
|
||||
int maxX = Clamp(frame.x + frame.w, 0, parentWidth);
|
||||
int minY = Clamp(frame.y, 0, parentHeight);
|
||||
int maxY = Clamp(frame.y + frame.h, 0, parentHeight);
|
||||
|
||||
SetWindowPos(layer->hWnd,
|
||||
HWND_TOP,
|
||||
point.x + minX * scale.x,
|
||||
point.y + minY * scale.y,
|
||||
(maxX - minX) * scale.x,
|
||||
(maxY - minY) * scale.y,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
|
||||
//TODO test if we should we guard against 0-width windows
|
||||
}
|
||||
|
||||
static void win32_update_child_layers(mp_window_data* window)
|
||||
{
|
||||
RECT clientRect;
|
||||
|
@ -287,29 +254,19 @@ static void win32_update_child_layers(mp_window_data* window)
|
|||
POINT point = {0};
|
||||
ClientToScreen(window->win32.hWnd, &point);
|
||||
|
||||
u32 dpi = GetDpiForWindow(window->win32.hWnd);
|
||||
vec2 scale = (vec2){(float)dpi/96., (float)dpi/96.};
|
||||
|
||||
int parentWidth = (clientRect.right - clientRect.left)/scale.x;
|
||||
int parentHeight = (clientRect.bottom - clientRect.top)/scale.y;
|
||||
int clientWidth = (clientRect.right - clientRect.left);
|
||||
int clientHeight = (clientRect.bottom - clientRect.top);
|
||||
|
||||
HWND insertAfter = window->win32.hWnd;
|
||||
|
||||
for_list(&window->win32.layers, layer, mp_layer, listElt)
|
||||
{
|
||||
mp_rect frame = layer->userFrame;
|
||||
|
||||
int minX = Clamp(frame.x, 0, parentWidth);
|
||||
int maxX = Clamp(frame.x + frame.w, 0, parentWidth);
|
||||
int minY = Clamp(frame.y, 0, parentHeight);
|
||||
int maxY = Clamp(frame.y + frame.h, 0, parentHeight);
|
||||
|
||||
SetWindowPos(layer->hWnd,
|
||||
insertAfter,
|
||||
point.x + minX * scale.x,
|
||||
point.y + minY * scale.y,
|
||||
(maxX - minX) * scale.x,
|
||||
(maxY - minY) * scale.y,
|
||||
point.x,
|
||||
point.y,
|
||||
clientWidth,
|
||||
clientHeight,
|
||||
SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOZORDER);
|
||||
|
||||
insertAfter = layer->hWnd;
|
||||
|
@ -967,14 +924,17 @@ vec2 mg_win32_surface_contents_scaling(mg_surface_data* surface)
|
|||
return(contentsScaling);
|
||||
}
|
||||
|
||||
mp_rect mg_win32_surface_get_frame(mg_surface_data* surface)
|
||||
vec2 mg_win32_surface_get_size(mg_surface_data* surface)
|
||||
{
|
||||
return(surface->layer.userFrame);
|
||||
}
|
||||
|
||||
void mg_win32_surface_set_frame(mg_surface_data* surface, mp_rect frame)
|
||||
{
|
||||
mg_win32_layer_set_frame(&surface->layer, frame);
|
||||
vec2 size = {0};
|
||||
RECT rect;
|
||||
if(GetClientRect(surface->layer.hWnd, &rect))
|
||||
{
|
||||
u32 dpi = GetDpiForWindow(surface->layer.hWnd);
|
||||
f32 scale = (float)dpi/96.;
|
||||
size = (vec2){(rect.right - rect.left)/scale, (rect.bottom - rect.top)/scale};
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
|
||||
bool mg_win32_surface_get_hidden(mg_surface_data* surface)
|
||||
|
@ -1039,8 +999,7 @@ LRESULT LayerWinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lPar
|
|||
void mg_surface_init_for_window(mg_surface_data* surface, mp_window_data* window)
|
||||
{
|
||||
surface->contentsScaling = mg_win32_surface_contents_scaling;
|
||||
surface->getFrame = mg_win32_surface_get_frame;
|
||||
surface->setFrame = mg_win32_surface_set_frame;
|
||||
surface->getSize = mg_win32_surface_get_size;
|
||||
surface->getHidden = mg_win32_surface_get_hidden;
|
||||
surface->setHidden = mg_win32_surface_set_hidden;
|
||||
surface->nativeLayer = mg_win32_surface_native_layer;
|
||||
|
@ -1059,17 +1018,12 @@ void mg_surface_init_for_window(mg_surface_data* surface, mp_window_data* window
|
|||
POINT point = {0};
|
||||
ClientToScreen(window->win32.hWnd, &point);
|
||||
|
||||
int width = parentRect.right - parentRect.left;
|
||||
int height = parentRect.bottom - parentRect.top;
|
||||
|
||||
u32 dpi = GetDpiForWindow(window->win32.hWnd);
|
||||
vec2 scale = (vec2){(float)dpi/96., (float)dpi/96.};
|
||||
|
||||
surface->layer.userFrame = (mp_rect){0, 0, width / scale.x, height / scale.y};
|
||||
int clientWidth = parentRect.right - parentRect.left;
|
||||
int clientHeight = parentRect.bottom - parentRect.top;
|
||||
|
||||
surface->layer.hWnd = CreateWindow("layer_window_class", "layer",
|
||||
WS_POPUP | WS_VISIBLE,
|
||||
point.x, point.y, width, height,
|
||||
point.x, point.y, clientWidth, clientHeight,
|
||||
window->win32.hWnd,
|
||||
0,
|
||||
layerWindowClass.hInstance,
|
||||
|
@ -1097,8 +1051,7 @@ void mg_surface_init_for_window(mg_surface_data* surface, mp_window_data* window
|
|||
void mg_surface_init_remote(mg_surface_data* surface, u32 width, u32 height)
|
||||
{
|
||||
surface->contentsScaling = mg_win32_surface_contents_scaling;
|
||||
surface->getFrame = mg_win32_surface_get_frame;
|
||||
surface->setFrame = mg_win32_surface_set_frame;
|
||||
surface->getSize = mg_win32_surface_get_size;
|
||||
surface->getHidden = mg_win32_surface_get_hidden;
|
||||
surface->setHidden = mg_win32_surface_set_hidden;
|
||||
surface->nativeLayer = mg_win32_surface_native_layer;
|
||||
|
|
|
@ -28,7 +28,6 @@ typedef struct mp_layer
|
|||
{
|
||||
mp_window_data* parent;
|
||||
list_elt listElt;
|
||||
mp_rect userFrame;
|
||||
HWND hWnd;
|
||||
} mp_layer;
|
||||
|
||||
|
|
Loading…
Reference in New Issue