Skip to content

Commit

Permalink
Merge branch 'hidpi'
Browse files Browse the repository at this point in the history
  • Loading branch information
Cloudef committed Jul 29, 2016
2 parents 1f7251f + e9d8e98 commit fbbac8d
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 55 deletions.
12 changes: 11 additions & 1 deletion example/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ relayout(wlc_handle output)
// you probably don't want to layout certain type of windows in wm

const struct wlc_size *r;
if (!(r = wlc_output_get_resolution(output)))
if (!(r = wlc_output_get_virtual_resolution(output)))
return;

size_t memb;
Expand Down Expand Up @@ -174,6 +174,16 @@ keyboard_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifie
char *terminal = (getenv("TERMINAL") ? getenv("TERMINAL") : "weston-terminal");
wlc_exec(terminal, (char *const[]){ terminal, NULL });
return true;
} else if (modifiers->mods & WLC_BIT_MOD_CTRL && sym >= XKB_KEY_1 && sym <= XKB_KEY_9) {
size_t memb;
const wlc_handle *outputs = wlc_get_outputs(&memb);
const uint32_t scale = (sym - XKB_KEY_1) + 1;

for (size_t i = 0; i < memb; ++i)
wlc_output_set_resolution(outputs[i], wlc_output_get_resolution(outputs[i]), scale);

printf("scale: %u\n", scale);
return true;
}
}

Expand Down
18 changes: 16 additions & 2 deletions include/wlc/wlc.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,25 @@ bool wlc_output_get_sleep(wlc_handle output);
/** Wake up / sleep. */
void wlc_output_set_sleep(wlc_handle output, bool sleep);

/** Get resolution. */
/**
* Get real resolution.
* Resolution applied by either wlc_output_set_resolution call or initially.
* Do not use this for coordinate boundary.
*/
const struct wlc_size* wlc_output_get_resolution(wlc_handle output);

/**
* Get virtual resolution.
* Resolution with transformations applied for proper rendering for example on high density displays.
* Use this to figure out coordinate boundary.
*/
const struct wlc_size* wlc_output_get_virtual_resolution(wlc_handle output);

/** Set resolution. */
WLC_NONULL void wlc_output_set_resolution(wlc_handle output, const struct wlc_size *resolution);
WLC_NONULL void wlc_output_set_resolution(wlc_handle output, const struct wlc_size *resolution, uint32_t scale);

/** Get scale factor. */
uint32_t wlc_output_get_scale(wlc_handle output);

/** Get current visibility bitmask. */
uint32_t wlc_output_get_mask(wlc_handle output);
Expand Down
61 changes: 41 additions & 20 deletions src/compositor/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ output_push_to_resource(struct wlc_output *output, wlc_resource r)
(output->information.model.data ? output->information.model.data : "model"),
output->information.transform);

assert(output->information.scale > 0);
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
wl_output_send_scale(resource, output->information.scale);
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) {
assert(output->scale > 0);
wl_output_send_scale(resource, output->scale);
}

struct wlc_output_mode *mode;
chck_iter_pool_for_each(&output->information.modes, mode) {
Expand Down Expand Up @@ -164,7 +165,7 @@ get_visible_views(struct wlc_output *output, struct chck_iter_pool *visible)
{
assert(output && output->blit);

const size_t gsz = output->resolution.w * output->resolution.h;
const size_t gsz = output->virtual.w * output->virtual.h;
memset(output->blit, false, gsz);

wlc_handle *h;
Expand Down Expand Up @@ -197,12 +198,12 @@ get_visible_views(struct wlc_output *output, struct chck_iter_pool *visible)
struct wlc_geometry o;
struct wlc_point a, b;
const bool should_blit = wlc_view_get_opaque(v, &o);
a.x = chck_clamp32(o.origin.x, 0, output->resolution.w);
a.y = chck_clamp32(o.origin.y, 0, output->resolution.h);
b.x = chck_clamp32((o.origin.x + o.size.w), 1, output->resolution.w);
b.y = chck_clamp32((o.origin.y + o.size.h), 1, output->resolution.h);
a.x = chck_clamp32(o.origin.x, 0, output->virtual.w);
a.y = chck_clamp32(o.origin.y, 0, output->virtual.h);
b.x = chck_clamp32((o.origin.x + o.size.w), 1, output->virtual.w);
b.y = chck_clamp32((o.origin.y + o.size.h), 1, output->virtual.h);

if (!blit(output->blit, &output->resolution, &a, &b, should_blit)) {
if (!blit(output->blit, &output->virtual, &a, &b, should_blit)) {
wlc_dlog(WLC_DBG_RENDER_LOOP, "%" PRIuWLC " is not visible (%d,%d+%d,%d %d,%d+%ux%u)", *h, a.x, a.y, b.x, b.y, o.origin.x, o.origin.y, o.size.w, o.size.h);
continue;
}
Expand Down Expand Up @@ -321,7 +322,7 @@ repaint(struct wlc_output *output)
return false;
}

wlc_render_resolution(&output->render, &output->context, &output->mode, &output->resolution);
wlc_render_resolution(&output->render, &output->context, &output->mode, &output->virtual, output->scale);

if (output->state.sleeping) {
// fake sleep
Expand Down Expand Up @@ -649,7 +650,7 @@ wlc_output_set_information(struct wlc_output *output, struct wlc_output_informat
wlc_log(WLC_LOG_INFO, "%s Chose mode (%u) %dx%d", output->information.name.data, output->active.mode, mode->width, mode->height);
output->mode = (struct wlc_size){ mode->width, mode->height };
mode->flags |= WL_OUTPUT_MODE_CURRENT;
set_resolution = wlc_output_set_resolution_ptr(output, &output->mode);
set_resolution = wlc_output_set_resolution_ptr(output, &output->mode, output->scale);
}

if (!set_resolution)
Expand Down Expand Up @@ -747,24 +748,28 @@ wlc_output_link_view(struct wlc_output *output, struct wlc_view *view, enum outp
}

bool
wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size *resolution)
wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size *resolution, uint32_t scale)
{
if (!output)
return false;

assert(resolution && resolution->w != 0 && resolution->h != 0);
assert(resolution && resolution->w != 0 && resolution->h != 0 && scale != 0);

if (resolution->w == 0 || resolution->h == 0) {
wlc_log(WLC_LOG_WARN, "Tried to set resolution of output %" PRIuWLC "to %ux%u", convert_to_wlc_handle(output), resolution->w, resolution->h);
if (resolution->w == 0 || resolution->h == 0 || scale == 0) {
wlc_log(WLC_LOG_WARN, "Tried to set resolution of output %" PRIuWLC "to %ux%u / %u", convert_to_wlc_handle(output), resolution->w, resolution->h, scale);
return false;
}

if (wlc_size_equals(resolution, &output->resolution))
if (output->scale == scale && wlc_size_equals(resolution, &output->resolution))
return false;

struct wlc_size virtual = *resolution;
virtual.w /= scale;
virtual.h /= scale;

size_t gsz;
if (chck_mul_ofsz(resolution->w, resolution->h, &gsz)) {
wlc_log(WLC_LOG_WARN, "Requested resolution %ux%u overflows when multiplied, ignoring resolution", resolution->w, resolution->h);
if (chck_mul_ofsz(virtual.w, virtual.h, &gsz)) {
wlc_log(WLC_LOG_WARN, "Requested resolution %ux%u (%ux%u) overflows when multiplied, ignoring resolution", resolution->w, resolution->h, virtual.w, virtual.h);
return false;
}

Expand All @@ -773,6 +778,8 @@ wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size *

struct wlc_size old = output->resolution;
output->resolution = *resolution;
output->virtual = virtual;
output->scale = scale;

output_push_to_resources(output);
WLC_INTERFACE_EMIT(output.resolution, convert_to_wlc_handle(output), &old, &output->resolution);
Expand Down Expand Up @@ -874,10 +881,23 @@ wlc_output_get_resolution(wlc_handle output)
return get(convert_from_wlc_handle(output, "output"), offsetof(struct wlc_output, resolution));
}

WLC_API const struct wlc_size*
wlc_output_get_virtual_resolution(wlc_handle output)
{
return get(convert_from_wlc_handle(output, "output"), offsetof(struct wlc_output, virtual));
}

WLC_API void
wlc_output_set_resolution(wlc_handle output, const struct wlc_size *resolution)
wlc_output_set_resolution(wlc_handle output, const struct wlc_size *resolution, uint32_t scale)
{
wlc_output_set_resolution_ptr(convert_from_wlc_handle(output, "output"), resolution, scale);
}

WLC_API uint32_t
wlc_output_get_scale(wlc_handle output)
{
wlc_output_set_resolution_ptr(convert_from_wlc_handle(output, "output"), resolution);
void *ptr = get(convert_from_wlc_handle(output, "output"), offsetof(struct wlc_output, scale));
return (ptr ? *(uint32_t*)ptr : 1);
}

WLC_API bool
Expand Down Expand Up @@ -1003,6 +1023,7 @@ wlc_output(struct wlc_output *output)

output->active.mode = UINT_MAX;
output->state.ims = 41;
output->scale = 1;

wlc_output_set_sleep_ptr(output, false);
wlc_output_set_mask_ptr(output, (1<<0));
Expand Down
9 changes: 6 additions & 3 deletions src/compositor/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,14 @@ struct wlc_output_information {
int32_t x, y;
int32_t physical_width, physical_height;
int32_t subpixel;
int32_t scale;
uint32_t connector_id;
enum wl_output_transform transform;
enum wlc_connector_type connector;
};

struct wlc_output {
struct wlc_source resources;
struct wlc_size mode, resolution;
struct wlc_size mode, resolution, virtual;
struct wlc_output_information information;
struct wlc_backend_surface bsurface;
struct wlc_context context;
Expand All @@ -55,6 +54,10 @@ struct wlc_output {
// Used to do visibility checks
bool *blit;

// Scale of the output
// Affects virtual resolution by dividing with the scale
uint32_t scale;

struct {
struct wl_event_source *idle;
} timer;
Expand Down Expand Up @@ -102,7 +105,7 @@ WLC_NONULL bool wlc_output(struct wlc_output *output);

void wlc_output_focus_ptr(struct wlc_output *output);
void wlc_output_set_sleep_ptr(struct wlc_output *output, bool sleep);
WLC_NONULLV(2) bool wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size *resolution);
WLC_NONULLV(2) bool wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size *resolution, uint32_t scale);
void wlc_output_set_mask_ptr(struct wlc_output *output, uint32_t mask);
WLC_NONULLV(2) void wlc_output_get_pixels_ptr(struct wlc_output *output, bool (*pixels)(const struct wlc_size *size, uint8_t *rgba, void *arg), void *arg);
bool wlc_output_set_views_ptr(struct wlc_output *output, const wlc_handle *views, size_t memb);
Expand Down
11 changes: 3 additions & 8 deletions src/compositor/seat/seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,12 @@ input_event(struct wl_listener *listener, void *data)

struct wlc_input_event *ev = data;
struct wlc_output *output = convert_from_wlc_handle(compositor->active.output, "output");

const struct wlc_size resolution = (output ? output->virtual : wlc_size_zero);

switch (ev->type) {
case WLC_INPUT_EVENT_MOTION:
{
const struct wlc_size resolution = (output ? output->resolution : wlc_size_zero);

const struct wlc_pointer_origin pos = {
chck_clamp(seat->pointer.pos.x + ev->motion.dx, 0, resolution.w),
chck_clamp(seat->pointer.pos.y + ev->motion.dy, 0, resolution.h),
Expand All @@ -162,8 +163,6 @@ input_event(struct wl_listener *listener, void *data)

case WLC_INPUT_EVENT_MOTION_ABSOLUTE:
{
const struct wlc_size resolution = (output ? output->resolution : wlc_size_zero);

const struct wlc_pointer_origin pos = {
ev->motion_abs.x(ev->motion_abs.internal, resolution.w),
ev->motion_abs.y(ev->motion_abs.internal, resolution.h)
Expand All @@ -183,8 +182,6 @@ input_event(struct wl_listener *listener, void *data)

case WLC_INPUT_EVENT_BUTTON:
{
const struct wlc_size resolution = (output ? output->resolution : wlc_size_zero);

const struct wlc_pointer_origin pos = {
chck_clamp(seat->pointer.pos.x, 0, resolution.w),
chck_clamp(seat->pointer.pos.y, 0, resolution.h),
Expand All @@ -203,8 +200,6 @@ input_event(struct wl_listener *listener, void *data)

case WLC_INPUT_EVENT_TOUCH:
{
const struct wlc_size resolution = (output ? output->resolution : wlc_size_zero);

struct wlc_point pos = {0, 0};

if (ev->touch.x && ev->touch.y && ev->touch.internal) {
Expand Down
1 change: 0 additions & 1 deletion src/platform/backend/drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@ query_drm(int fd, struct chck_iter_pool *out_infos)
info->info.physical_width = connector->mmWidth;
info->info.physical_height = connector->mmHeight;
info->info.subpixel = connector->subpixel;
info->info.scale = 1; // weston gets this from config?
info->info.connector_id = connector->connector_type_id;
info->info.connector = wlc_connector_for_drm_connector(connector->connector_type);

Expand Down
3 changes: 1 addition & 2 deletions src/platform/backend/x11.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ x11_event(int fd, uint32_t mask, void *data)
struct wlc_output *output;
if ((output = output_for_window(&compositor->outputs.pool, ev->window))) {
output->mode = (struct wlc_size){ ev->width, ev->height };
wlc_output_set_resolution_ptr(output, &output->mode); // XXX: make a request?
wlc_output_set_resolution_ptr(output, &output->mode, output->scale); // XXX: make a request?
}
}
break;
Expand Down Expand Up @@ -312,7 +312,6 @@ fake_information(struct wlc_output_information *info, uint32_t id)
wlc_output_information(info);
chck_string_set_cstr(&info->make, "Xorg", false);
chck_string_set_cstr(&info->model, "X11 Window", false);
info->scale = 1;
info->connector = WLC_CONNECTOR_WLC;
info->connector_id = id;

Expand Down
20 changes: 15 additions & 5 deletions src/platform/render/gles2.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ struct ctx {
} programs[PROGRAM_LAST];

struct wlc_size resolution, mode;
uint32_t scale;

GLuint textures[TEXTURE_LAST];
GLuint clear_fbo;
GLenum internal_format;
GLenum preferred_type;
bool native_resolution;
bool fakefb_dirty;

struct {
Expand Down Expand Up @@ -422,9 +425,9 @@ clear_fakefb(struct ctx *context)
}

static void
resolution(struct ctx *context, const struct wlc_size *mode, const struct wlc_size *resolution)
resolution(struct ctx *context, const struct wlc_size *mode, const struct wlc_size *resolution, uint32_t scale)
{
assert(context && resolution);
assert(context && resolution && scale > 0);

if (!wlc_size_equals(&context->resolution, resolution)) {
for (GLuint i = 0; i < PROGRAM_LAST; ++i) {
Expand All @@ -442,6 +445,10 @@ resolution(struct ctx *context, const struct wlc_size *mode, const struct wlc_si
GL_CALL(glViewport(0, 0, mode->w, mode->h));
context->mode = *mode;
}

struct wlc_size virtual = { .w = mode->w / (float)scale, .h = mode->h / (float)scale };
context->native_resolution = wlc_size_equals(resolution, &virtual);
context->scale = scale;
}

static void
Expand Down Expand Up @@ -678,7 +685,7 @@ texture_paint(struct ctx *context, GLuint *textures, GLuint nmemb, const struct
GL_CALL(glActiveTexture(GL_TEXTURE0 + i));
GL_CALL(glBindTexture(GL_TEXTURE_2D, textures[i]));

if (settings->filter || !wlc_size_equals(&context->resolution, &context->mode)) {
if (settings->filter || !context->native_resolution) {
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
} else {
Expand All @@ -699,6 +706,9 @@ surface_paint_internal(struct ctx *context, struct wlc_surface *surface, const s

const struct wlc_geometry *g = geometry;

assert(surface->commit.scale >= 1);
settings->filter = ((uint32_t)surface->commit.scale != context->scale);

if (!wlc_size_equals(&surface->size, &geometry->size)) {
if (wlc_geometry_equals(&settings->visible, geometry)) {
settings->filter = true;
Expand Down Expand Up @@ -819,7 +829,7 @@ read_pixels(struct ctx *context, enum wlc_pixel_format format, const struct wlc_
(void)context;
assert(context && geometry && out_geometry && out_data);
struct wlc_geometry g = *geometry;
clamp_to_bounds(&g, &context->resolution);
clamp_to_bounds(&g, &context->mode);
GL_CALL(glReadPixels(g.origin.x, g.origin.y, g.size.w, g.size.h, format_map[format].format, format_map[format].type, out_data));
*out_geometry = g;
}
Expand All @@ -830,7 +840,7 @@ write_pixels(struct ctx *context, enum wlc_pixel_format format, const struct wlc
(void)context;
assert(context && geometry && data);
struct wlc_geometry g = *geometry;
clamp_to_bounds(&g, &context->resolution);
clamp_to_bounds(&g, &context->mode);
GL_CALL(glBindTexture(GL_TEXTURE_2D, context->textures[TEXTURE_FAKEFB]));
GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, g.origin.x, g.origin.y, g.size.w, g.size.h, format_map[format].format, format_map[format].type, data));
context->fakefb_dirty = true;
Expand Down
4 changes: 2 additions & 2 deletions src/platform/render/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
#include "gles2.h"

void
wlc_render_resolution(struct wlc_render *render, struct wlc_context *bound, const struct wlc_size *mode, const struct wlc_size *resolution)
wlc_render_resolution(struct wlc_render *render, struct wlc_context *bound, const struct wlc_size *mode, const struct wlc_size *resolution, uint32_t scale)
{
assert(render && bound && mode && resolution);

if (!render->api.resolution || !wlc_context_bind(bound))
return;

render->api.resolution(render->render, mode, resolution);
render->api.resolution(render->render, mode, resolution, scale);
}

void
Expand Down
Loading

0 comments on commit fbbac8d

Please sign in to comment.