client的设置方法:

region = wl_compositor_create_region(window->display->compositor);
wl_region_add(region, 0, 0,window->geometry.width,window->geometry.height);
wl_surface_set_opaque_region(window->surface, region);
wl_region_destroy(region);

server的对应操作:


static void
compositor_create_region(struct wl_client *client,struct wl_resource *resource, uint32_t id)
{struct weston_region *region;//创建region对象region = malloc(sizeof *region);
...pixman_region32_init(&region->region);//通过pixman对region进行初始化region->resource =wl_resource_create(client, &wl_region_interface, 1, id);//真正创建weston里面的object,初始化。
...wl_resource_set_implementation(region->resource, &region_interface,region, destroy_region);//任然是初始化的一部分。
}
初始化weston_region以及他的resource

static void
region_add(struct wl_client *client, struct wl_resource *resource,int32_t x, int32_t y, int32_t width, int32_t height)
{struct weston_region *region = wl_resource_get_user_data(resource);pixman_region32_union_rect(&region->region, &region->region,x, y, width, height);
}
//其实就是通过pixman对region创建一个矩形区域。

static void
surface_set_opaque_region(struct wl_client *client,struct wl_resource *resource,struct wl_resource *region_resource)
{struct weston_surface *surface = wl_resource_get_user_data(resource);struct weston_region *region;if (region_resource) {region = wl_resource_get_user_data(region_resource);pixman_region32_copy(&surface->pending.opaque,&region->region);} else {pixman_region32_clear(&surface->pending.opaque);}
}
//把surface与region进行一个绑定,如果region参数为null。则清空surface的region区域;
当然现在还是更新的pending部分,没有实际应用。不commit都是pending
理论上这个值只设置一次就可以。但是建议在不性能考虑的时候每次commit都设置一下。
static void
region_destroy(struct wl_client *client, struct wl_resource *resource)
{wl_resource_destroy(resource);
}
//释放resource

总的来说很简单,client遵循完全一致的操作逻辑,server这边也是中规中矩的简单操作。后面就要看commit以及后续怎么处理region,如下是commit以后server对pending state的处理

 /* wl_surface.set_opaque_region */pixman_region32_init(&opaque);pixman_region32_intersect_rect(&opaque, &state->opaque,0, 0, surface->width, surface->height);//主要是和surface的区域做一个交集的动作,取交集部分作为不透明区域if (!pixman_region32_equal(&opaque, &surface->opaque)) {pixman_region32_copy(&surface->opaque, &opaque);//把对应的区域拷贝到surface里面,而不是pending的了。wl_list_for_each(view, &surface->views, surface_link)weston_view_geometry_dirty(view);//简单也简单,就是view->transform.dirty = 1;属性}pixman_region32_fini(&opaque);pending 的不透明区域并不会因为一帧完整的commit而消失,所以理论上设置一次即可。

关于region这块区域要从头开始,先是在view的创建过程中创建region:

WL_EXPORT struct weston_view *
weston_view_create(struct weston_surface *surface)
{struct weston_view *view;
...view->surface = surface;view->plane = &surface->compositor->primary_plane;/* Assign to surface */wl_list_insert(&surface->views, &view->surface_link);wl_signal_init(&view->destroy_signal);wl_list_init(&view->link);wl_list_init(&view->layer_link.link);pixman_region32_init(&view->clip);view->alpha = 1.0;pixman_region32_init(&view->transform.opaque);wl_list_init(&view->geometry.transformation_list);wl_list_insert(&view->geometry.transformation_list,&view->transform.position.link);weston_matrix_init(&view->transform.position.matrix);wl_list_init(&view->geometry.child_list);pixman_region32_init(&view->geometry.scissor);pixman_region32_init(&view->transform.boundingbox);view->transform.dirty = 1;return view;
}

boundingbox区域(view的全局坐标):


weston_view_update_transform_enable:pixman_region32_init_rect(&surfregion, 0, 0,view->surface->width, view->surface->height);weston_view_update_transform_scissor(view, &surfregion);
surfbox = pixman_region32_extents(&surfregion);view_compute_bbox(view, surfbox, &view->transform.boundingbox);
pixman_region32_fini(&surfregion);先创建一个完整的surface区域:0,0,w,h。
如果有裁剪,则对surface区域做一个裁剪,此时任然是局部的。static void
view_compute_bbox(struct weston_view *view, const pixman_box32_t *inbox,pixman_region32_t *bbox)
{float min_x = HUGE_VALF,  min_y = HUGE_VALF;float max_x = -HUGE_VALF, max_y = -HUGE_VALF;int32_t s[4][2] = {{ inbox->x1, inbox->y1 },{ inbox->x1, inbox->y2 },{ inbox->x2, inbox->y1 },{ inbox->x2, inbox->y2 },};//确立矩形区域float int_x, int_y;int i;if (inbox->x1 == inbox->x2 || inbox->y1 == inbox->y2) {/* avoid rounding empty bbox to 1x1 */pixman_region32_init(bbox);return;}//如果x1与x2相等,就是没宽度,如果y1与y2相等,就是没长度,也就是个0for (i = 0; i < 4; ++i) {float x, y;weston_view_to_global_float(view, s[i][0], s[i][1], &x, &y);if (x < min_x)min_x = x;if (x > max_x)max_x = x;if (y < min_y)min_y = y;if (y > max_y)max_y = y;}int_x = floorf(min_x);int_y = floorf(min_y);pixman_region32_init_rect(bbox, int_x, int_y,ceilf(max_x) - int_x, ceilf(max_y) - int_y);//基本上就是 surface.x + view->geomerty.x 与 surface.y + view->geomerty.y和对应的w,h。
}WL_EXPORT void
weston_view_to_global_float(struct weston_view *view,float sx, float sy, float *x, float *y)
{if (view->transform.enabled) {struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };weston_matrix_transform(&view->transform.matrix, &v);if (fabsf(v.f[3]) < 1e-6) {weston_log("warning: numerical instability in ""%s(), divisor = %g\n", __func__,v.f[3]);*x = 0;*y = 0;return;}*x = v.f[0] / v.f[3];*y = v.f[1] / v.f[3];} else {*x = sx + view->geometry.x;*y = sy + view->geometry.y;}//如果有变化,就要做对应的变化,如果没有,就是surface的x或y + view->geomerty,x或y。
}weston_view_from_global_float
正好和上面的相反。

weston_view_set_position:设置view的绝对坐标。

weston_view_damage_belowview->transform.boundingbox - view->clip = damage
计算全局的view坐标减去clip的坐标,得到真正需要处理的属于此view的坐标大小,送给plane->damage
clip坐标为其他覆盖在此view上的不透明区域。weston_surface_assign_outputview->transform,boundingbox & view->output->region
让view的output坐标和 boundingbox坐标取交集。
说是重新计算surface的view在哪些output上面。注意,是通过view所在的outputmask来得到surface所在的output。weston_view_assign_outputview->transform.boundingbox & output->region
让view的boundingbox坐标和 output坐标取交集,注意这部分是通过output做的遍历。
重新计算view在哪些output上面。一般是先执行weston_view_assign_output决定了view在哪些output上,然后再调用
weston_surface_assgin_outputweston_view_update_transform_disable
weston_view_update_transform_enable
暂时还不明确用途。weston_view_update_transformweston_view_matches_output_entirely
确认view的boundingbox是否覆盖了对应的output的所有区域,如果是返回true,否则返回false。weston_compositor_pick_viewweston_view_destroy
如名字view_accumulate_damage

讲述一下gl_renderer_repaint_output


/* NOTE: We now allow falling back to ARGB gl visuals when XRGB is* unavailable, so we're assuming the background has no transparency* and that everything with a blend, like drop shadows, will have something* opaque (like the background) drawn underneath it.** Depending on the underlying hardware, violating that assumption could* result in seeing through to another display plane.*/
static void
gl_renderer_repaint_output(struct weston_output *output,pixman_region32_t *output_damage)
{weston_log("%s+++\n",  __func__);struct gl_output_state *go = get_output_state(output);struct weston_compositor *compositor = output->compositor;struct gl_renderer *gr = get_renderer(compositor);EGLBoolean ret;static int errored;/* areas we've damaged since we last used this buffer */pixman_region32_t previous_damage;/* total area we need to repaint this time */pixman_region32_t total_damage;enum gl_border_status border_status = BORDER_STATUS_CLEAN;struct weston_view *view;if (use_output(output) < 0)  //本质就是调用eglMakeCurrent,详细见:https://www.zybuluo.com/SR1s/note/650099return;/* Clear the used_in_output_repaint flag, so that we can properly track* which surfaces were used in this output repaint. */wl_list_for_each_reverse(view, &compositor->view_list, link) {if (view->plane == &compositor->primary_plane) {struct gl_surface_state *gs =get_surface_state(view->surface);gs->used_in_output_repaint = false;}}//设置这个used_in_output_repaint标志位。这个标志位在调用gpu函数进行绘画时置为true。
而绘画完成后置为false。主要用于说明对应surface所处状态。正在被output_repaint所用。if (go->begin_render_sync != EGL_NO_SYNC_KHR)gr->destroy_sync(gr->egl_display, go->begin_render_sync);if (go->end_render_sync != EGL_NO_SYNC_KHR)gr->destroy_sync(gr->egl_display, go->end_render_sync);//名副其实的render sync机制,后面需要学习一下,看上去是用来保证个glrender的开始和结束状态。go->begin_render_sync = create_render_sync(gr);/* Calculate the global GL matrix */go->output_matrix = output->matrix;weston_matrix_translate(&go->output_matrix,-(output->current_mode->width / 2.0),-(output->current_mode->height / 2.0), 0);weston_matrix_scale(&go->output_matrix,2.0 / output->current_mode->width,-2.0 / output->current_mode->height, 1);/* If using shadow, redirect all drawing to it first. */if (shadow_exists(go)) {/* XXX: Shadow code does not support resizing. */assert(output->current_mode->width == go->shadow.width);assert(output->current_mode->height == go->shadow.height);glBindFramebuffer(GL_FRAMEBUFFER, go->shadow.fbo);glViewport(0, 0, go->shadow.width, go->shadow.height);} else {glBindFramebuffer(GL_FRAMEBUFFER, 0);glViewport(go->borders[GL_RENDERER_BORDER_LEFT].width,go->borders[GL_RENDERER_BORDER_BOTTOM].height,output->current_mode->width,output->current_mode->height);}/* In fan debug mode, redraw everything to make sure that we clear any* fans left over from previous draws on this buffer.* This precludes the use of EGL_EXT_swap_buffers_with_damage and* EGL_KHR_partial_update, since we damage the whole area. */if (gr->fan_debug) {pixman_region32_t undamaged;pixman_region32_init(&undamaged);pixman_region32_subtract(&undamaged, &output->region,output_damage);gr->fan_debug = false;repaint_views(output, &undamaged);gr->fan_debug = true;pixman_region32_fini(&undamaged);}/* previous_damage covers regions damaged in previous paints since we* last used this buffer */pixman_region32_init(&previous_damage);pixman_region32_init(&total_damage); /* total area to redraw *//* Update previous_damage using buffer_age (if available), and store* current damaged region for future use. */output_get_damage(output, &previous_damage, &border_status);output_rotate_damage(output, output_damage, go->border_status);/* Redraw both areas which have changed since we last used this buffer,* as well as the areas we now want to repaint, to make sure the* buffer is up to date. */pixman_region32_union(&total_damage, &previous_damage, output_damage);border_status |= go->border_status;if (gr->has_egl_partial_update && !gr->fan_debug) {int n_egl_rects;EGLint *egl_rects;/* For partial_update, we need to pass the region which has* changed since we last rendered into this specific buffer;* this is total_damage. */pixman_region_to_egl_y_invert(output, &total_damage,&egl_rects, &n_egl_rects);gr->set_damage_region(gr->egl_display, go->egl_surface,egl_rects, n_egl_rects);free(egl_rects);}if (shadow_exists(go)) {/* Repaint into shadow. */if (compositor->test_data.test_quirks.gl_force_full_redraw_of_shadow_fb)repaint_views(output, &output->region);elserepaint_views(output, output_damage);glBindFramebuffer(GL_FRAMEBUFFER, 0);glViewport(go->borders[GL_RENDERER_BORDER_LEFT].width,go->borders[GL_RENDERER_BORDER_BOTTOM].height,output->current_mode->width,output->current_mode->height);blit_shadow_to_output(output, &total_damage);} else {repaint_views(output, &total_damage);}pixman_region32_fini(&total_damage);pixman_region32_fini(&previous_damage);draw_output_borders(output, border_status);wl_signal_emit(&output->frame_signal, output_damage);go->end_render_sync = create_render_sync(gr);if (gr->swap_buffers_with_damage && !gr->fan_debug) {int n_egl_rects;EGLint *egl_rects;/* For swap_buffers_with_damage, we need to pass the region* which has changed since the previous SwapBuffers on this* surface - this is output_damage. */pixman_region_to_egl_y_invert(output, output_damage,&egl_rects, &n_egl_rects);ret = gr->swap_buffers_with_damage(gr->egl_display,go->egl_surface,egl_rects, n_egl_rects);free(egl_rects);} else {ret = eglSwapBuffers(gr->egl_display, go->egl_surface);}if (ret == EGL_FALSE && !errored) {errored = 1;weston_log("Failed in eglSwapBuffers.\n");gl_renderer_print_egl_error_state();}go->border_status = BORDER_STATUS_CLEAN;/* We have to submit the render sync objects after swap buffers, since* the objects get assigned a valid sync file fd only after a gl flush.*/timeline_submit_render_sync(gr, output, go->begin_render_sync,TIMELINE_RENDER_POINT_TYPE_BEGIN);timeline_submit_render_sync(gr, output, go->end_render_sync,TIMELINE_RENDER_POINT_TYPE_END);update_buffer_release_fences(compositor, output);gl_renderer_garbage_collect_programs(gr);weston_log("%s---\n",  __func__);
}

随后的调用就在draw_view也就是合成的地方了

/* repaint bounding region in global coordinates: */
pixman_region32_t repaint;
/* opaque region in surface coordinates: */
pixman_region32_t surface_opaque;
/* non-opaque region in surface coordinates: */
pixman_region32_t surface_blend;
//总共三个区域,一个是全局的repaint。
//另外两个则是相对surface的 surface opaque和surface blendpixman_region32_init(&repaint);
pixman_region32_intersect(&repaint,&ev->transform.boundingbox, damage);
pixman_region32_subtract(&repaint, &repaint, &ev->clip);
//以上是以全局坐标去考虑区域的。也就是repaint的区域是全局中的damage区域。再减去一个view的clip区域,
//注意这个是绝对坐标哦!也就是全局坐标/* blended region is whole surface minus opaque region: */
pixman_region32_init_rect(&surface_blend, 0, 0,ev->surface->width, ev->surface->height);
//先假设全部区域都是可混合的,再找到最终和混合区域if (ev->geometry.scissor_enabled)pixman_region32_intersect(&surface_blend, &surface_blend,&ev->geometry.scissor);pixman_region32_subtract(&surface_blend, &surface_blend,&ev->surface->opaque);
//合成的时候是从下往上画的。上面用到opaque region也很简单,这个view哪些部分是blend区域,
//哪部分是opaque区域。注意这个坐标是对应surface自己的相对坐标哦!/* XXX: Should we be using ev->transform.opaque here? */pixman_region32_init(&surface_opaque);if (ev->geometry.scissor_enabled)pixman_region32_intersect(&surface_opaque,&ev->surface->opaque,&ev->geometry.scissor);elsepixman_region32_copy(&surface_opaque, &ev->surface->opaque);//同样的,找到相对应surface的相对的不透明区域
....
....if (pixman_region32_not_empty(&surface_opaque)) {struct gl_shader_config alt = sconf;if (alt.req.variant == SHADER_VARIANT_RGBA) {/* Special case for RGBA textures with possibly* bad data in alpha channel: use the shader* that forces texture alpha = 1.0.* Xwayland surfaces need this.*/alt.req.variant = SHADER_VARIANT_RGBX;}if (ev->alpha < 1.0)glEnable(GL_BLEND);elseglDisable(GL_BLEND);repaint_region(gr, ev, &repaint, &surface_opaque, &alt);gs->used_in_output_repaint = true;}if (pixman_region32_not_empty(&surface_blend)) {glEnable(GL_BLEND);repaint_region(gr, ev, &repaint, &surface_blend, &sconf);gs->used_in_output_repaint = true;}
//先画不透明的区域,然后画除此之外的blending区域,那传入的一个是全局坐标,
//一个是相对surface的坐标,是如何真正完成绘画的呢?

要绘制的最后一个区域是“region”和“surf_region”的交集。 但是,'region' 在全局坐标中,'surf_region' 在表面局部坐标中。 texture_region() 将迭代来自两个区域的所有矩形对,计算每对矩形的交集多边形,如果它具有非零区域(实际上至少有 3 个顶点),则将其存储为三角形扇形。

static void
repaint_region(struct gl_renderer *gr,struct weston_view *ev,pixman_region32_t *region,pixman_region32_t *surf_region,const struct gl_shader_config *sconf)
{GLfloat *v;unsigned int *vtxcnt;int i, first, nfans;/* The final region to be painted is the intersection of* 'region' and 'surf_region'. However, 'region' is in the global* coordinates, and 'surf_region' is in the surface-local* coordinates. texture_region() will iterate over all pairs of* rectangles from both regions, compute the intersection* polygon for each pair, and store it as a triangle fan if* it has a non-zero area (at least 3 vertices, actually).*/nfans = texture_region(ev, region, surf_region);v = gr->vertices.data;vtxcnt = gr->vtxcnt.data;/* position: */glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[0]);glEnableVertexAttribArray(0);/* texcoord: */glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[2]);glEnableVertexAttribArray(1);if (!gl_renderer_use_program(gr, sconf)) {gl_renderer_send_shader_error(ev);/* continue drawing with the fallback shader */}for (i = 0, first = 0; i < nfans; i++) {glDrawArrays(GL_TRIANGLE_FAN, first, vtxcnt[i]);if (gr->fan_debug)triangle_fan_debug(gr, sconf, first, vtxcnt[i]);first += vtxcnt[i];}glDisableVertexAttribArray(1);glDisableVertexAttribArray(0);gr->vertices.size = 0;gr->vtxcnt.size = 0;
}

NOTE:

build view list的时候是从上到下的顺序(先塞入的在view list的最下面)。draw view的时候,是从下到上。
下,即离我们最远的,如bakcground开始。
上,即离我们最近的,如focus。

[21:27:53.413] weston_compositor_build_view_list : ++++
[21:27:53.413] view_list_add : view:0x5619cd4097c0++++
[21:27:53.413] weston_view_update_transform : view:0x5619cd4097c0++++
[21:27:53.413] view_list_add : view:0x5619cd2149d0++++
[21:27:53.413] weston_view_update_transform : view:0x5619cd2149d0++++
[21:27:53.413] view_list_add : view:0x5619cd401d80++++
[21:27:53.413] weston_view_update_transform : view:0x5619cd401d80++++
[21:27:53.413] weston_view_damage_below : view:0x5619cd401d80++++
[21:27:53.413] weston_view_damage_below : view:0x5619cd401d80----
[21:27:53.413] weston_view_update_transform_enable : view:0x5619cd401d80++++
[21:27:53.413] view_compute_bbox++++
[21:27:53.413] view_compute_bbox----
[21:27:53.413] weston_view_update_transform_enable : view:0x5619cd401d80----
[21:27:53.413] weston_view_damage_below : view:0x5619cd401d80++++
[21:27:53.413] weston_view_damage_below : view:0x5619cd401d80----
[21:27:53.413] weston_view_assign_output : view:0x5619cd401d80++++
[21:27:53.413] weston_surface_assign_output : surface:0x5619cd365ae0++++
[21:27:53.413] weston_surface_assign_output : surface:0x5619cd365ae0----
[21:27:53.413] weston_view_assign_output : view:0x5619cd401d80----
[21:27:53.413] weston_view_update_transform : view:0x5619cd401d80----
[21:27:53.413] view_list_add : view:0x5619cd235680++++
[21:27:53.413] weston_view_update_transform : view:0x5619cd235680++++
[21:27:53.413] weston_compositor_build_view_list : ----
[21:27:53.413] output_accumulate_damage : ++++
[21:27:53.413] view_accumulate_damage : view:0x5619cd4097c0++++
[21:27:53.414] view_accumulate_damage : view:0x5619cd4097c0----
[21:27:53.414] view_accumulate_damage : view:0x5619cd2149d0++++
[21:27:53.414] view_accumulate_damage : view:0x5619cd2149d0----
[21:27:53.414] view_accumulate_damage : view:0x5619cd401d80++++
[21:27:53.414] view_compute_bbox++++
[21:27:53.414] view_accumulate_damage : view:0x5619cd401d80----
[21:27:53.414] view_accumulate_damage : view:0x5619cd235680++++
[21:27:53.414] view_accumulate_damage : view:0x5619cd235680----
[21:27:53.414] output_accumulate_damage : ---
[21:27:53.414] gl_renderer_repaint_output+++
[21:27:53.414] repaint_views
[21:27:53.414] repaint_views:plane 0 0
[21:27:53.414] draw_view : view:0x5619cd235680++++
[21:27:53.414] damage region 0 0 1024 640
[21:27:53.414] boundingbox region 0 0 1024 640
[21:27:53.414] repaint region= boundingbox & damage 0 0 1024 640
[21:27:53.414] surface blend region 0 0 0 0
[21:27:53.414] surface opaque region 0 0 1024 640
[21:27:53.414] repaint opaque region++
[21:27:53.414] repaint_region:region 0 0 1024 640
[21:27:53.414] repaint_region:surf region 0 0 1024 640
[21:27:53.414] repaint opaque region--
[21:27:53.414] draw_view : view:0x5619cd235680----[21:27:53.414] repaint_views:plane 0 0
[21:27:53.414] draw_view : view:0x5619cd401d80++++
[21:27:53.414] damage region 0 0 1024 640
[21:27:53.414] boundingbox region 175 93 981 584
[21:27:53.414] repaint region= boundingbox & damage 175 93 981 584
[21:27:53.414] surface blend region 0 0 806 491
[21:27:53.414] surface opaque region 35 35 771 456
[21:27:53.414] repaint opaque region++
[21:27:53.414] repaint_region:region 175 93 981 584
[21:27:53.414] repaint_region:surf region 35 35 771 456
[21:27:53.414] repaint opaque region--
[21:27:53.414] repaint blend region++
[21:27:53.414] repaint_region:region 175 93 981 584
[21:27:53.414] repaint_region:surf region 0 0 806 491
[21:27:53.414] repaint blend region--
[21:27:53.414] draw_view : view:0x5619cd401d80----[21:27:53.414] repaint_views:plane 0 0
[21:27:53.414] draw_view : view:0x5619cd2149d0++++
[21:27:53.414] damage region 0 0 1024 640
[21:27:53.414] boundingbox region 0 0 1024 32
[21:27:53.414] repaint region= boundingbox & damage 0 0 1024 32
[21:27:53.414] surface blend region 0 0 1024 32
[21:27:53.414] surface opaque region 0 0 0 0
[21:27:53.414] repaint blend region++
[21:27:53.414] repaint_region:region 0 0 1024 32
[21:27:53.414] repaint_region:surf region 0 0 1024 32
[21:27:53.414] repaint blend region--
[21:27:53.414] draw_view : view:0x5619cd2149d0----[21:27:53.414] repaint_views:plane 0 0
[21:27:53.414] draw_view : view:0x5619cd4097c0++++
[21:27:53.414] damage region 0 0 1024 640
[21:27:53.414] boundingbox region 1003 -3 1035 29
[21:27:53.414] repaint region= boundingbox & damage 1003 0 1024 29
[21:27:53.414] surface blend region 0 0 32 32
[21:27:53.414] surface opaque region 0 0 0 0
[21:27:53.414] repaint blend region++
[21:27:53.414] repaint_region:region 1003 0 1024 29
[21:27:53.414] repaint_region:surf region 0 0 32 32
[21:27:53.414] repaint blend region--
[21:27:53.414] draw_view : view:0x5619cd4097c0----[21:27:53.421] gl_renderer_repaint_output---

display: weston: opaque region笔记相关推荐

  1. display:weston渲染流程:commit

    接上一篇 display:weston渲染流程:buffer+attach+damage+frame display:weston渲染流程:buffer+attach+damage+frame_maz ...

  2. display:weston:weston-simple-egl: server端

    接上篇:https://blog.csdn.net/u012839187/article/details/112415876 surface_attch以及surface_damage相关就不讲了,参 ...

  3. display:weston:weston-simple-egl

    写在前面: 客户端渲染 在Wayland架构中,客户端UI的所有呈现均由客户端代码执行,通常由客户端使用的图形工具包执行. 图形工具箱可以使用其希望呈现UI元素的任何方法:在CPU上进行软件呈现,使用 ...

  4. display:weston的client端绘画[subsurface,fullscreen]

    weston的源代码里面有关于client的绘画例子 建议追踪https://github.com/wayland-project/weston/blob/master/clients/ 增加一种功能 ...

  5. CSS基础-标签显示模式(display)【学习笔记】

    标签的三种显示模式 三种显示模式的特点以及区别 三种显示模式的相互转化 什么是标签显示模式 什么是标签的显示模式? 标签以什么方式进行显示,比如div 自己占一行, 比如span 一行可以放很多个 作 ...

  6. display:grid的一些笔记

    display: grid;grid-template-columns: repeat(3, 1fr); /* 相当于 1fr 1fr 1fr */grid-template-rows: repeat ...

  7. display:Weston:怎么让某个surface永远置于顶层

    问题如标题:假设我有一个app.想一直置于顶层,那么我可以怎么做? 1.drm-master权限问题 想办法拿掉weston或者说drm关于master权限的处理,然后自己基于libdrm画一个即可. ...

  8. GEE(Google Earth Engine) 代码学习笔记一 快速入门

    GEE 代码学习笔记一 (GEE 基于JavaScript语言和python语言,我记录的是JavaScript语言) 1.GEE 快速入门 quick start. 2.基本语句 - 简单输出 pr ...

  9. 学习笔记——GEE\USGS\地理空间数据云\ENVI反复横跳的心酸过程

    整个问题实际上是在用GEE做无监督分类时,发现影像拼接色彩差距较大.出现明显拼接缝的问题,在尝试了网上已有的直方图匹配算法之后效果不佳且经常溢出,所以回归本心用ENVI去校正,试图获得色彩统一的整个影 ...

最新文章

  1. Java学习笔记(5)——泛型
  2. 转:要么学习,要么走人!直面竞争的30条生存原则
  3. 如何在matlab sfunction 函数中调用自己写的函数?
  4. jar2exe 配置jre
  5. php与mysql同步_MySQL 同步(一)
  6. Meidapipe 3D手势姿态跟踪算法,手机端实时检测 ,多个手势同时捕捉
  7. 软件外包中常见的七个错误之一 - 不懂用户需求
  8. C++ Web编程实战
  9. python爬取景点数据看该去哪里玩——南京篇
  10. STM32L0系列单片机低功耗(STOP)使用+RTC唤醒+LPUART(DMA方式)唤醒+LPTIM唤醒
  11. linux中iso文件怎么安装,linux系统安装iso文件方法
  12. nack fec心得
  13. 免费的PDF转换器有哪些?小圆象PDF转换器办公达人必备工具
  14. 计算机式硬盘录像机,全面分析PC式硬盘录像机十大问题
  15. webapp期末作业-oneapp
  16. 2018_2_3_Boolean Expressions_栈_模拟
  17. 一种留存分析的方案:Cohort Analysis
  18. 自识别标记(self-identifying marker) -(2) 用于相机标定的CALTag介绍
  19. jvm-014(张龙老师jvm教程) ClassLoader 源码doc文档及数组类加载器
  20. 推荐十本C#编程的最佳书籍

热门文章

  1. 省市县(区) 地区SQL
  2. L2TP连接错误 789 解决方法
  3. hadoop mpp oracle,请教一下MPP 与 Hadoop是什么关系?
  4. 9款HTML5实现的超酷特效
  5. 使用Palm®(奔迈)Mojo 框架开发JavaScript程序 #1
  6. 夏天到了,专家教你如何挤乳沟
  7. 很火的美丽天天秒—链动2+1模式来啦
  8. 雷电战机---附源码
  9. 【直流传动与控制系统】第12周CDIO工作报告
  10. 汽车诊断之UDS入门-0x27(SecurityAccess)安全访问