当前位置: 首页 > news >正文

Linux内核4.14版本——drm框架分析(4)——crtc分析

目录

1. struct drm_crtc结构体

2. crtc相关的API

2.1 drm_crtc_init_with_planes

2.5 drm_mode_setcrtc

3. func的一些介绍

3.1 struct drm_crtc_helper_funcs

3.2 struct drm_crtc_funcs

4. 应用层的调用

4.1 drmModeSetCrtc (drmlib库里)---> drm_mode_setcrtc


       本文主要分析一下crtc相关的内容。

1. struct drm_crtc结构体


/*** struct drm_crtc - central CRTC control structure* @dev: parent DRM device* @port: OF node used by drm_of_find_possible_crtcs()* @head: list management* @name: human readable name, can be overwritten by the driver* @mutex: per-CRTC locking* @base: base KMS object for ID tracking etc.* @primary: primary plane for this CRTC* @cursor: cursor plane for this CRTC* @cursor_x: current x position of the cursor, used for universal cursor planes* @cursor_y: current y position of the cursor, used for universal cursor planes* @enabled: is this CRTC enabled?* @mode: current mode timings* @hwmode: mode timings as programmed to hw regs* @x: x position on screen* @y: y position on screen* @funcs: CRTC control functions* @gamma_size: size of gamma ramp* @gamma_store: gamma ramp values* @helper_private: mid-layer private data* @properties: property tracking for this CRTC** Each CRTC may have one or more connectors associated with it.  This structure* allows the CRTC to be controlled.*/
struct drm_crtc {struct drm_device *dev;struct device_node *port;struct list_head head;char *name;/*** @mutex:** This provides a read lock for the overall CRTC state (mode, dpms* state, ...) and a write lock for everything which can be update* without a full modeset (fb, cursor data, CRTC properties ...). A full* modeset also need to grab &drm_mode_config.connection_mutex.** For atomic drivers specifically this protects @state.*/struct drm_modeset_lock mutex;struct drm_mode_object base;/* primary and cursor planes for CRTC */struct drm_plane *primary;struct drm_plane *cursor;/*** @index: Position inside the mode_config.list, can be used as an array* index. It is invariant over the lifetime of the CRTC.*/unsigned index;/* position of cursor plane on crtc */int cursor_x;int cursor_y;bool enabled;/* Requested mode from modesetting. */struct drm_display_mode mode;/* Programmed mode in hw, after adjustments for encoders,* crtc, panel scaling etc. Needed for timestamping etc.*/struct drm_display_mode hwmode;int x, y;const struct drm_crtc_funcs *funcs;/* Legacy FB CRTC gamma size for reporting to userspace */uint32_t gamma_size;uint16_t *gamma_store;/* if you are using the helper */const struct drm_crtc_helper_funcs *helper_private;struct drm_object_properties properties;/*** @state:** Current atomic state for this CRTC.** This is protected by @mutex. Note that nonblocking atomic commits* access the current CRTC state without taking locks. Either by going* through the &struct drm_atomic_state pointers, see* for_each_crtc_in_state(), for_each_oldnew_crtc_in_state(),* for_each_old_crtc_in_state() and for_each_new_crtc_in_state(). Or* through careful ordering of atomic commit operations as implemented* in the atomic helpers, see &struct drm_crtc_commit.*/struct drm_crtc_state *state;/*** @commit_list:** List of &drm_crtc_commit structures tracking pending commits.* Protected by @commit_lock. This list doesn't hold its own full* reference, but burrows it from the ongoing commit. Commit entries* must be removed from this list once the commit is fully completed,* but before it's correspoding &drm_atomic_state gets destroyed.*/struct list_head commit_list;/*** @commit_lock:** Spinlock to protect @commit_list.*/spinlock_t commit_lock;#ifdef CONFIG_DEBUG_FS/*** @debugfs_entry:** Debugfs directory for this CRTC.*/struct dentry *debugfs_entry;
#endif/*** @crc:** Configuration settings of CRC capture.*/struct drm_crtc_crc crc;/*** @fence_context:** timeline context used for fence operations.*/unsigned int fence_context;/*** @fence_lock:** spinlock to protect the fences in the fence_context.*/spinlock_t fence_lock;/*** @fence_seqno:** Seqno variable used as monotonic counter for the fences* created on the CRTC's timeline.*/unsigned long fence_seqno;/*** @timeline_name:** The name of the CRTC's fence timeline.*/char timeline_name[32];
};

2. crtc相关的API

2.1 drm_crtc_init_with_planes


/*** drm_crtc_init_with_planes - Initialise a new CRTC object with*    specified primary and cursor planes.* @dev: DRM device* @crtc: CRTC object to init* @primary: Primary plane for CRTC* @cursor: Cursor plane for CRTC* @funcs: callbacks for the new CRTC* @name: printf style format string for the CRTC name, or NULL for default name** Inits a new object created as base part of a driver crtc object. Drivers* should use this function instead of drm_crtc_init(), which is only provided* for backwards compatibility with drivers which do not yet support universal* planes). For really simple hardware which has only 1 plane look at* drm_simple_display_pipe_init() instead.** Returns:* Zero on success, error code on failure.*/
int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,struct drm_plane *primary,struct drm_plane *cursor,const struct drm_crtc_funcs *funcs,const char *name, ...)
{struct drm_mode_config *config = &dev->mode_config;int ret;WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);crtc->dev = dev;crtc->funcs = funcs;INIT_LIST_HEAD(&crtc->commit_list);spin_lock_init(&crtc->commit_lock);drm_modeset_lock_init(&crtc->mutex);ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);   // (1)if (ret)return ret;if (name) {                                          // (2)va_list ap;va_start(ap, name);crtc->name = kvasprintf(GFP_KERNEL, name, ap);va_end(ap);} else {crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",drm_num_crtcs(dev));}if (!crtc->name) {drm_mode_object_unregister(dev, &crtc->base);return -ENOMEM;}crtc->fence_context = dma_fence_context_alloc(1);     // (3)spin_lock_init(&crtc->fence_lock);snprintf(crtc->timeline_name, sizeof(crtc->timeline_name),"CRTC:%d-%s", crtc->base.id, crtc->name);crtc->base.properties = &crtc->properties;           // (4)list_add_tail(&crtc->head, &config->crtc_list);crtc->index = config->num_crtc++;crtc->primary = primary;                             // (5) crtc->cursor = cursor;if (primary && !primary->possible_crtcs)primary->possible_crtcs = 1 << drm_crtc_index(crtc);if (cursor && !cursor->possible_crtcs)cursor->possible_crtcs = 1 << drm_crtc_index(crtc);ret = drm_crtc_crc_init(crtc);                      // (6)if (ret) {drm_mode_object_unregister(dev, &crtc->base);return ret;}if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {     // (7)drm_object_attach_property(&crtc->base, config->prop_active, 0);drm_object_attach_property(&crtc->base, config->prop_mode_id, 0);drm_object_attach_property(&crtc->base,config->prop_out_fence_ptr, 0);}return 0;
}

        (1)创建一个类型为DRM_MODE_OBJECT_CRTC的struct drm_mode_object结构体。

        (2)为创建的crtc赋名字。

        (3)暂不知道。

        (4)初始化properties

        (5)初始化primary plane、cursor plane。

        (6)drm_crtc_crc_init是一些调试方面的。

        (7)attach一些properties变量。

2.5 drm_mode_setcrtc

int drm_mode_setcrtc(struct drm_device *dev, void *data,struct drm_file *file_priv)
{struct drm_mode_config *config = &dev->mode_config;struct drm_mode_crtc *crtc_req = data;struct drm_crtc *crtc;struct drm_connector **connector_set = NULL, *connector;struct drm_framebuffer *fb = NULL;struct drm_display_mode *mode = NULL;struct drm_mode_set set;uint32_t __user *set_connectors_ptr;struct drm_modeset_acquire_ctx ctx;int ret;int i;if (!drm_core_check_feature(dev, DRIVER_MODESET))return -EINVAL;/** Universal plane src offsets are only 16.16, prevent havoc for* drivers using universal plane code internally.*/if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)return -ERANGE;crtc = drm_crtc_find(dev, crtc_req->crtc_id);             // (1)if (!crtc) {DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);return -ENOENT;}DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);mutex_lock(&crtc->dev->mode_config.mutex);drm_modeset_acquire_init(&ctx, 0);                       // (2)
retry:ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);         // (3)if (ret)goto out;if (crtc_req->mode_valid) {                              /* If we have a mode we need a framebuffer. *//* If we pass -1, set the mode with the currently bound fb */if (crtc_req->fb_id == -1) {                         // (4)           if (!crtc->primary->fb) {DRM_DEBUG_KMS("CRTC doesn't have current FB\n");ret = -EINVAL;goto out;}fb = crtc->primary->fb;/* Make refcounting symmetric with the lookup path. */drm_framebuffer_get(fb);} else {fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);if (!fb) {DRM_DEBUG_KMS("Unknown FB ID%d\n",crtc_req->fb_id);ret = -ENOENT;goto out;}}mode = drm_mode_create(dev);                       // (5)if (!mode) {ret = -ENOMEM;goto out;}ret = drm_mode_convert_umode(mode, &crtc_req->mode);   // (6)if (ret) {DRM_DEBUG_KMS("Invalid mode\n");goto out;}/** Check whether the primary plane supports the fb pixel format.* Drivers not implementing the universal planes API use a* default formats list provided by the DRM core which doesn't* match real hardware capabilities. Skip the check in that* case.*/if (!crtc->primary->format_default) {                  // (7)ret = drm_plane_check_pixel_format(crtc->primary,fb->format->format);if (ret) {struct drm_format_name_buf format_name;DRM_DEBUG_KMS("Invalid pixel format %s\n",drm_get_format_name(fb->format->format,&format_name));goto out;}}ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,mode, fb);                           // (8)if (ret)goto out;}if (crtc_req->count_connectors == 0 && mode) {DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");ret = -EINVAL;goto out;}if (crtc_req->count_connectors > 0 && (!mode || !fb)) {DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",crtc_req->count_connectors);ret = -EINVAL;goto out;}if (crtc_req->count_connectors > 0) {               u32 out_id;/* Avoid unbounded kernel memory allocation */if (crtc_req->count_connectors > config->num_connector) {ret = -EINVAL;goto out;}connector_set = kmalloc_array(crtc_req->count_connectors,sizeof(struct drm_connector *),GFP_KERNEL);if (!connector_set) {ret = -ENOMEM;goto out;}for (i = 0; i < crtc_req->count_connectors; i++) {        // (9)connector_set[i] = NULL;set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;if (get_user(out_id, &set_connectors_ptr[i])) {ret = -EFAULT;goto out;}connector = drm_connector_lookup(dev, out_id);         // (10)if (!connector) {DRM_DEBUG_KMS("Connector id %d unknown\n",out_id);ret = -ENOENT;goto out;}DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",connector->base.id,connector->name);connector_set[i] = connector;}}set.crtc = crtc;set.x = crtc_req->x;set.y = crtc_req->y;set.mode = mode;set.connectors = connector_set;set.num_connectors = crtc_req->count_connectors;set.fb = fb;ret = __drm_mode_set_config_internal(&set, &ctx);            // (11)out:if (fb)drm_framebuffer_put(fb);                                 // (12)if (connector_set) {for (i = 0; i < crtc_req->count_connectors; i++) {if (connector_set[i])drm_connector_put(connector_set[i]);             // (13)}}kfree(connector_set);drm_mode_destroy(dev, mode);if (ret == -EDEADLK) {drm_modeset_backoff(&ctx);goto retry;}drm_modeset_drop_locks(&ctx);drm_modeset_acquire_fini(&ctx);mutex_unlock(&crtc->dev->mode_config.mutex);return ret;
}

        (1)找到需要的crtc实体。

        (2)初始化一个ctrc的需求内容结构体。

        (3)connection、crtc、plane等锁上锁。 

        (4)得到或者生成primary plane的framebuffer。

        (5~6)创建一个struct drm_display_mode结构体,并把应用层传递下来的参数赋值给给结构体。

        (7)检查primary plane支持的pixel format。

        (8)检查一下framebuffer是否足够大,能否满足crtc viewport.

        (9~10)找到crtc绑定链接的connetcor。

        (11)设置struct drm_mode_set结构体。

3. func的一些介绍

3.1 struct drm_crtc_helper_funcs

 
//struct drm_crtc_helper_funcs - helper operations for CRTCs
struct drm_crtc_helper_funcs {//电源管理接口,一般由drm_helper_connector_dpms调用void (*dpms)(struct drm_crtc *crtc, int mode);/*为modeset做准备,一般就是调用dpms接口关闭crtc(DRM_MODE_DPMS_OFF),    *drm_crtc_heler_set_mode接口会调用*atomic接口使用atomic_disable替代*/void (*prepare)(struct drm_crtc *crtc);/* 和prepare接口对应,是在modeset完成后,调用该接口来enable crtc* 一般就是调用dmps接口( DRM_MODE_DPMS_ON)* atomic 操作是用atomic_enable替代*/void (*commit)(struct drm_crtc *crtc);/*检查显示mode的有效性,  drm_helper_probe_single_connector_modes()和* drm_atomic_helper_check_modeset()会调用到, 该接口仅作初步检查* 更详细的检查有@mode_fixup or @atomic_check*/enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,const struct drm_display_mode *mode);/*验证并修正mode, 由drm_atomic_helper_check_modeset()调用*/bool (*mode_fixup)(struct drm_crtc *crtc,const struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode);//设置display mode ,crtc_set_mode会调用该接口int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,struct drm_display_mode *adjusted_mode, int x, int y,struct drm_framebuffer *old_fb);/*更新crtc的display mode, 但不会修改其primary plane配置,* 注意调用该接口的时候, display pipe应该是完全off的*/void (*mode_set_nofb)(struct drm_crtc *crtc);//设置fb 和 显示位置, drm_crtc_helper_set_config()会调用该接口int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,struct drm_framebuffer *old_fb);int (*mode_set_base_atomic)(struct drm_crtc *crtc,struct drm_framebuffer *fb, int x, int y,enum mode_set_atomic);//关闭crtcvoid (*disable)(struct drm_crtc *crtc);/*检查待更新的drm_crtc_state, * drm_atomic_helper_check() -->  drm_atomic_helper_check_planes()会调用*/int (*atomic_check)(struct drm_crtc *crtc,struct drm_atomic_state *state);//多plane的atomic update之前需要调用该接口(drm_atomic_helper_commit_planes中调用)void (*atomic_begin)(struct drm_crtc *crtc,struct drm_atomic_state *state);/*多plane的atomic update之后需要调用该接口(drm_atomic_helper_commit_planes中调用)* atomic_begin/atomic_flush具体的作用好像也不是太清晰,应该就是为driver提供在更新* planes的前后能做一些额外操作吧?*/void (*atomic_flush)(struct drm_crtc *crtc,struct drm_atomic_state *state);//atomic encable crtcvoid (*atomic_enable)(struct drm_crtc *crtc,struct drm_atomic_state *state);atomic disable crtcvoid (*atomic_disable)(struct drm_crtc *crtc,struct drm_atomic_state *state);//获取扫描信息,由drm_crtc_vblank_helper_get_vblank_timestamp()调用bool (*get_scanout_position)(struct drm_crtc *crtc,bool in_vblank_irq, int *vpos, int *hpos,ktime_t *stime, ktime_t *etime,const struct drm_display_mode *mode);
};

3.2 struct drm_crtc_funcs

 
//crtc控制接口,一般填写helper函数
struct drm_crtc_funcs {/*重置软硬件state, 由drm_mode_config_reset()调用,一般赋值为        drm_atomic_helper_crtc_reset()接口*/void (*reset)(struct drm_crtc *crtc);/*设置鼠标图片, width/height应该是鼠标图片的宽高, handle是鼠标图片buf(drm_gem_obj)对        应的handle, 该接口最新版本已经被废弃,使用鼠标层代替*/int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height);/*同上,设置鼠标图片,不过这个接口多了hot_x, hot_y坐标*/int (*cursor_set2)(struct drm_crtc *crtc, struct drm_file *file_priv,uint32_t handle, uint32_t width, uint32_t height,int32_t hot_x, int32_t hot_y);/*鼠标移动操作*/int (*cursor_move)(struct drm_crtc *crtc, int x, int y);//gamma设置int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,uint32_t size,struct drm_modeset_acquire_ctx *ctx);//drm_mode_config_cleanup 调用到该接口void (*destroy)(struct drm_crtc *crtc);/* 设置crtc的fb/ connector/ mode的属性,对应用户态drmModeSetCrtc接口* atomic modeset操作,使用drm_atomic_helper_set_config接口赋值*/int (*set_config)(struct drm_mode_set *set,struct drm_modeset_acquire_ctx *ctx);//page翻转接口,vsync同步的int (*page_flip)(struct drm_crtc *crtc,struct drm_framebuffer *fb,struct drm_pending_vblank_event *event,uint32_t flags,struct drm_modeset_acquire_ctx *ctx);//和page_flip类似,但该接口会等待特定的vbankint (*page_flip_target)(struct drm_crtc *crtc,struct drm_framebuffer *fb,struct drm_pending_vblank_event *event,uint32_t flags, uint32_t target,struct drm_modeset_acquire_ctx *ctx);//设置属性int (*set_property)(struct drm_crtc *crtc,struct drm_property *property, uint64_t val);//拷贝crtc的drm_crtc_state对象, 一般赋值为drm_atomic_helper_crtc_duplicate_state()struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc);void (*atomic_destroy_state)(struct drm_crtc *crtc,struct drm_crtc_state *state);//atomic 操作中设置特定属性值到state中,该接口一般可由drm_atomic_set_property调用int (*atomic_set_property)(struct drm_crtc *crtc,struct drm_crtc_state *state,struct drm_property *property,uint64_t val);//获取atomic属性int (*atomic_get_property)(struct drm_crtc *crtc,const struct drm_crtc_state *state,struct drm_property *property,uint64_t *val);//drm_dev_register之后,调用该接口进行额外的crtc操作int (*late_register)(struct drm_crtc *crtc);//与late_register接口相反, 在drm_dev_unregister之前调用void (*early_unregister)(struct drm_crtc *crtc);//以下接口与crc相关int (*set_crc_source)(struct drm_crtc *crtc, const char *source);int (*verify_crc_source)(struct drm_crtc *crtc, const char *source,size_t *values_cnt);const char *const *(*get_crc_sources)(struct drm_crtc *crtc,size_t *count);//打印crtc的atomic state属性值, 一般由drm_atomic_print_state调用void (*atomic_print_state)(struct drm_printer *p,const struct drm_crtc_state *state);//获取硬件vblank counter计数u32 (*get_vblank_counter)(struct drm_crtc *crtc);//使能vblank中断int (*enable_vblank)(struct drm_crtc *crtc);//关闭vbank中断void (*disable_vblank)(struct drm_crtc *crtc);//获取vblank时间戳bool (*get_vblank_timestamp)(struct drm_crtc *crtc,int *max_error,ktime_t *vblank_time,bool in_vblank_irq);
};

4. 应用层的调用

         crtc的设置主要有ACTIVE/MODE_ID属性, 其中MODE_ID属性,是设置其显示时序,常用的设置接口如下:

4.1 drmModeSetCrtc (drmlib库里)---> drm_mode_setcrtc

        该接口设置crtc的显示buf, 连接的connector_id, 显示时序mode, 从代码中可以看出来,该接口绑定fb到crtc时,实际上是绑定该crtc的primary plane上。前面已经介绍了。

相关文章:

Linux内核4.14版本——drm框架分析(4)——crtc分析

目录 1. struct drm_crtc结构体 2. crtc相关的API 2.1 drm_crtc_init_with_planes 2.5 drm_mode_setcrtc 3. func的一些介绍 3.1 struct drm_crtc_helper_funcs 3.2 struct drm_crtc_funcs 4. 应用层的调用 4.1 drmModeSetCrtc &#xff08;drmlib库里&#xff09;---…...

用原生js手写分页功能

分页功能如下&#xff1a; 数据分页显示&#xff0c;每页显示若干条数据&#xff0c;默认当前页码为第一页。例如&#xff1a;每页5条数据&#xff0c;则第一页显示 1-5 条&#xff0c;第二页显示 6-10 条&#xff0c;依此类推。当页码为第一页时&#xff0c;上一页为禁用状态…...

CornerNet介绍

CornerNet: Detecting Objects as Paired Keypoints ECCV 2018 Paper&#xff1a;https://arxiv.org/pdf/1808.01244v2.pdf Code&#xff1a;GitHub - princeton-vl/CornerNet 摘要&#xff1a; 提出了一种single-stage的目标检测算法CornerNet&#xff0c;它把每个目标检…...

【SpringBoot】日志使用

默认配置 Spring Boot默认帮我们配置好了日志 //记录器Logger logger LoggerFactory.getLogger(getClass());Testpublic void contextLoads() {//System.out.println();//日志的级别&#xff1b;//由低到高 trace<debug<info<warn<error//可以调整输出的日志级…...

关于slice扩容性能损耗的探究

背景 ​ 如果让我评选最伟大的数据结构&#xff0c;在我心中答案只有两个&#xff0c;数组和哈希表&#xff0c;这两个是我的程序的重要组成部分&#xff0c;同时也是我饭碗的重要组成部分。slice和map简洁明了的API很容易让我们有一种他们提供了无限大的空间&#xff0c;可以…...

Java实现单向链表

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;Java数据结构与算法 &#x1f9…...

3月4日,30秒知全网,精选7个热点

///印度最大供电商罕见于现货市场购煤&#xff0c;能源供应短缺成忧 据知情人士透露&#xff0c;这家印度国有发电公司计划在下周左右发布300万吨的招标 ///QQ音乐推出AIGC黑胶播放器 这是国内音乐行业首个运用AI技术&#xff0c;通过文字、图片指令快速生成不同风格的播放器…...

EXCEL-职业版本(2)

Excel-职业版本&#xff08;2&#xff09; 定位 1.如何快速定位到不连续的空值&#xff0c;填充为0 1.在任意空单元格里复制0 2.选中数据区域CtrlA 3.CtrlG 4.选择【定位条件】 5.选择【空值】 6.ctrlV 粘贴 即可 2.怎么一次性计算每个小组的数量 单价和金额的和? 1.选中…...

java中延时队列的实现

大家好&#xff0c;我是一名CRUD工程师&#xff0c;最近我朋友突然来问我如何实现延时队列&#xff0c;我脱口而出就是MQ。不过突然想到公司的项目好像用的是java的一个原生类。于是我就想着趁周末的时间好好的去探究一下各方法实现延时队列的优缺点。 延迟消息 延迟消息就是字…...

基于java的circle buffer的实现

总目录链接==>> AutoSAR入门和实战系列总目录 文章目录 缓冲区示例什么是循环缓冲区?方法 1:使用数组插入元素删除元素方法 2:使用链表插入元素:删除元素:当数据经常从一个地方移动到另一个地方或从一个进程移动到另一个进程或被频繁访问时,它不能存储在永久性内存…...

通用方法——为什么重写equals还要重写hashcode

本文介绍java.lang.Object类中的两个方法&#xff1a;equals和hashCode。这两个方法大家应该都知道&#xff0c;但是这两个方法的作用是什么、为什么重写equals还要重写hashCode、它们之间有什么关系和约定等&#xff0c;今天就来带大家了解一下。 1、hashCode hashCode即散列…...

JavaSE学习进阶day2_01 包和权限修饰符

第一章 包 1.1 包 包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术&#xff0c;不同的技术类放在不同的包下&#xff0c;方便管理和维护。 在IDEA项目中&#xff0c;建包的操作如下&#xff1a; 这个咱们在基础班就谈到过。 包名的命名规范&#xff1a; 路径…...

Android性能调优 - 省电优化

省电&#xff1a;通过工具Battery Historian查看到:耗电大头: 屏幕、网络、cpuled/oled屏幕显示:降低亮度&#xff0c;开深色模式&#xff1b;锁屏间隔缩短到 &#xff1b;亮屏需要一直持有唤醒锁&#xff0c;还有gps定位也需要用到唤醒锁;网络&#xff1a; 常用的网络优化措施…...

ElasticSearch - SpringBoot整合ES之全文搜索匹配查询 match

文章目录1. 数据准备2. match 匹配查询1. 全文检索2. 简化查询DSL语句3. match 匹配查询原理官方文档地址&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/index.html权威指南&#xff1a;https://www.elastic.co/guide/cn/elasticsearch/guide/current/…...

句子的改写和扩写

目录 1.句子改写 2.句子扩写 &#xff08;不低于15个句子算是长句子&#xff0c;不能太多长句子&#xff09; 1.句子改写 我绝不会嫁给你的。 如果你是世界上最后一个男人&#xff0c;我就去寺庙。 If you married me,I would jump into the well. 如果你嫁给我&#xff0c;我…...

DockerFile创建及案例

DockerFile dockerfile是用来构建docker镜像的文件&#xff0c;命令脚本参数脚本&#xff01; 构建步骤 编写一个dockerfile文件docker build 构建成为一个对象docker run 运行镜像docker push 发布镜像&#xff08;DockerHub、阿里云镜像仓库&#xff09; 去官网Docker-Hub…...

第十四届蓝桥杯三月真题刷题训练——第 1 天

目录 题目1&#xff1a;数列求值 代码&#xff1a; 题目2&#xff1a;质数 代码&#xff1a; 题目3&#xff1a;饮料换购 代码&#xff1a; 题目1&#xff1a;数列求值 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出…...

基于容器云提交spark job任务

容器云提交spark job任务 容器云提交KindJob类型的spark任务&#xff0c;首先需要申请具有Job任务提交权限的rbac&#xff0c;然后编写对应的yaml文件&#xff0c;通过spark内置的spark-submit命令&#xff0c;提交用户程序(jar包)到集群执行。 1、创建任务job提交权限rbac …...

Linux系统调用之目录操作函数

前言 如果&#xff0c;想要深入的学习Linux系统调用中mkdir&#xff0c;rmdir&#xff0c;rename&#xff0c;chdir&#xff0c;getcwd等这些有关于目录操作函数&#xff0c;还是需要去自己阅读Linux系统中的帮助文档。 具体输入命令&#xff1a; man 2 mkdir/rmdir/rename/ch…...

设计模式-策略模式

前言 作为一名合格的前端开发工程师&#xff0c;全面的掌握面向对象的设计思想非常重要&#xff0c;而“设计模式”是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的&#xff0c;代表了面向对象设计思想的最佳实践。正如《HeadFirst设计模式》中说的一句话&…...

Qwen-Image-Layered快速部署:ComfyUI镜像一键启动与配置

Qwen-Image-Layered快速部署&#xff1a;ComfyUI镜像一键启动与配置 1. 引言&#xff1a;图像分层的革命性突破 1.1 传统图像编辑的痛点 在常规的图像处理流程中&#xff0c;我们常常遇到一个根本性难题&#xff1a;图像一旦生成或拍摄完成&#xff0c;就变成了一个"不…...

Hermes社区贡献指南:如何参与项目开发和提交PR

Hermes社区贡献指南&#xff1a;如何参与项目开发和提交PR 【免费下载链接】hermes Golang package that generates clean, responsive HTML e-mails for sending transactional mail 项目地址: https://gitcode.com/gh_mirrors/he/hermes 想要为Hermes电子邮件生成库贡…...

计算机专业四类毕业生就业全景对比:数据背后的残酷真相与报考抉择

数据来源&#xff1a;麦可思研究院《2025中国本科生就业报告》、教育部《2025年全国普通高校毕业生就业质量年度报告》、工信部《2025网络安全产业人才发展报告》、牛客Moka《2025春季校园招聘白皮书》、代码随想录星球薪资报告、知乎/B站等平台校招实况、CSDN/虎嗅/21经济网等…...

别再手动写JSON Schema了!用智谱AI/DeepSeek的FunctionCall,5分钟搞定天气查询API对接

告别JSON Schema手写时代&#xff1a;用大模型FunctionCall极速对接天气API 开发聊天机器人时&#xff0c;最头疼的莫过于为每个新功能手动编写JSON Schema。上周我接手一个天气查询功能需求&#xff0c;原本预计要花半天时间定义参数结构、验证逻辑&#xff0c;结果用智谱AI的…...

有些路看起来很难走,其实是在带你慢慢变强

生活里&#xff0c;很多人都希望自己走的是一条轻松一点、顺利一点的路。最好努力了就能有结果&#xff0c;付出了就能被看见&#xff0c;遇到的问题也都能很快解决。可真正经历过一些事情后才会发现&#xff0c;人生并不会总按照理想的节奏前进。很多时候&#xff0c;那些让人…...

实战指南:利用快马平台为不同项目类型智能定制idea开发环境与工具链

今天想和大家分享一个实战经验&#xff1a;如何根据不同项目类型&#xff0c;快速定制专属的IDEA开发环境。作为开发者&#xff0c;我们经常需要切换不同技术栈&#xff0c;每次手动安装插件、配置SDK的过程实在太费时间。最近发现用InsCode(快马)平台可以智能解决这个问题&…...

5分钟掌握Fideo:终极免费直播录制软件使用指南

5分钟掌握Fideo&#xff1a;终极免费直播录制软件使用指南 【免费下载链接】fideo-live-record A convenient live broadcast recording software! Supports Tiktok, Youtube, Twitch, Bilibili, Bigo!(一款方便的直播录制软件! 支持tiktok, youtube, twitch, 抖音&#xff0c;…...

车辆纵向建模避坑指南:如何正确处理空气阻力与轮胎摩擦的耦合效应

车辆纵向建模避坑指南&#xff1a;如何正确处理空气阻力与轮胎摩擦的耦合效应 在自动驾驶仿真和车辆控制算法开发中&#xff0c;精确的纵向动力学建模是确保虚拟测试与实车表现一致性的关键。许多工程师都遇到过这样的困境&#xff1a;仿真环境下调参完美的模型&#xff0c;在…...

STEP3-VL-10B开源大模型部署:从HuggingFace下载到CSDN算力上线全过程

STEP3-VL-10B开源大模型部署&#xff1a;从HuggingFace下载到CSDN算力上线全过程 想体验一个能看懂图片、理解图表、甚至帮你分析复杂文档的AI助手吗&#xff1f;今天要介绍的STEP3-VL-10B&#xff0c;就是一个让你用普通显卡就能跑起来的“多面手”AI模型。 你可能听说过那些…...

前端Word文档生成革命:3分钟掌握纯JavaScript专业文档导出创新方案

前端Word文档生成革命&#xff1a;3分钟掌握纯JavaScript专业文档导出创新方案 【免费下载链接】DOCX.js Generate Microsoft Word DOCX files in pure client-side JavaScript. Try in Chrome 项目地址: https://gitcode.com/gh_mirrors/do/DOCX.js 还在为Word文档导出…...