SDL调试心得

今天在项目中用到SDL2.0的库做视频显示用,在其中出现不少问题,这里一一记录下来,并作为以后的参考。

同一个窗口句柄在多次使用SDL_CreateWindowFrom和SDL_DestroyWindow以后,发现程序运行正常,但视频显示不出来的问题。

第一次将Hwnd传递给SDL_CreateWindowFrom,创建一个显示窗口给SDL,随后在不使用的时候,调用SDL_DestroyWindow,将刚刚创建的显示窗口销毁,释放显示相关资源之后,然后在再次使用SDL_CreateWindowFrom的时候,将同一个句柄传递给SDL_CreateWindowFrom,返回成功,后续的操作也全部正常进行,但视频在窗口上始终显示不出来。

对于其中的原因,我找了好久,后面从SDL的源码中才慢慢推测并怀疑一些问题,SDL源码如下:

 1 void
 2 SDL_DestroyWindow(SDL_Window * window)
 3 {
 4     SDL_VideoDisplay *display;
 5
 6     CHECK_WINDOW_MAGIC(window, );
 7
 8     /* Restore video mode, etc. */
 9     SDL_HideWindow(window);/*注意这个地方哦*/
10
11     /* Make sure this window no longer has focus */
12     if (SDL_GetKeyboardFocus() == window) {
13         SDL_SetKeyboardFocus(NULL);
14     }
15     if (SDL_GetMouseFocus() == window) {
16         SDL_SetMouseFocus(NULL);
17     }
18
19     /* make no context current if this is the current context window. */
20     if (window->flags & SDL_WINDOW_OPENGL) {
21         if (_this->current_glwin == window) {
22             SDL_GL_MakeCurrent(window, NULL);
23         }
24     }
25
26     if (window->surface) {
27         window->surface->flags &= ~SDL_DONTFREE;
28         SDL_FreeSurface(window->surface);
29     }
30     if (_this->DestroyWindowFramebuffer) {
31         _this->DestroyWindowFramebuffer(_this, window);
32     }
33     if (_this->DestroyWindow) {
34         _this->DestroyWindow(_this, window);
35     }
36     if (window->flags & SDL_WINDOW_OPENGL) {
37         SDL_GL_UnloadLibrary();
38     }
39
40     display = SDL_GetDisplayForWindow(window);
41     if (display->fullscreen_window == window) {
42         display->fullscreen_window = NULL;
43     }
44
45     /* Now invalidate magic */
46     window->magic = NULL;
47
48     /* Free memory associated with the window */
49     SDL_free(window->title);
50     SDL_FreeSurface(window->icon);
51     SDL_free(window->gamma);
52     while (window->data) {
53         SDL_WindowUserData *data = window->data;
54
55         window->data = data->next;
56         SDL_free(data->name);
57         SDL_free(data);
58     }
59
60     /* Unlink the window from the list */
61     if (window->next) {
62         window->next->prev = window->prev;
63     }
64     if (window->prev) {
65         window->prev->next = window->next;
66     } else {
67         _this->windows = window->next;
68     }
69
70     SDL_free(window);
71 }

从上面的代码,我开始怀疑是不是在调用SDL_DestroyWindow以后,SDL将窗口给隐藏了,导致在上面显示视频的时候,始终显示不出来的问题。

于是我在自己的测试代码中加入如下语句,在调用SDL_DestroyWindow以后,我一句:

vDisplay.ShowWindow(SW_SHOWNORMAL);//想显示窗口给显示出来,show出来
其中vDisplay对应于显示的窗口控件对象。

在测试的项目代码中加入这行代码以后,就完美的解决了项目的问题。

=============================================================

问题2:

当我在MFC的UI消息相应函数中创建显示窗口的一些相关资源,在后台创建的单独线程,用于刷新和更新显示数据,然后在UI的关闭消息响应中释放和销毁SDL窗口相关资源。

问题来了,当我使用全屏的时候,出现了后台更新数据线程一直报错:

 1     if(o_pSdlHelper->SDL_RenderClear(pDispContext->pStruOut->pRender)<0)
 2     {
 3         char outstr[200]={0};
 4         const char *pbuf=o_pSdlHelper->SDL_GetError();
 5         _snprintf(outstr,sizeof(outstr),"%s \n",pbuf);//这里出错信息为:Reset(): INVALIDCALL
 6         OutputDebugStringA(outstr);
 7         memset(outstr,0,sizeof(outstr));
 8
 9         return PCI_MC_UNKNOWN_ERR;
10     }

这就让我奇怪了,之前我全屏的时候,没有错误啊,现在为什么有错?而且显示窗口画面也没有显示刷新了!!

于是我想了下和之前的代码有什么不同,唯一的不同在于,我调用创建窗口和创建渲染,纹理等等这些操作等资源放在了和更新数据的同一个线程中,没办法,不知道原因,只有改回原来的代码,将创建的代码从UI消息响应中调入和后台刷新数据同一个线程中。结果奇怪的是,居然这样全屏操作能运行?

见鬼了,这是啥原因?

//这个原因,还有待查证相关资料和SDL源码才能知道。暂时解决了,但不知道原因何在。

时间: 2024-11-03 05:28:57

SDL调试心得的相关文章

gdb调试心得

初学gdb调试心得 attach挂载之前,要在被调试程序中加sleep()等待,然后ps出进程pid,attach成功后,先在sleep处设置断点,其位置可以forward-search来寻找,然后用s或者n逐步调试,用c直接运行到下一个断点. 在运行中改变变量取值要先设置断点,然后set var xx=00.

LPC2478_调试心得(转)

1.在调试“E:\htwang\smart2200v201\ARM嵌入式系统实验教程(二)\开发板出厂编程程序\液晶显示程序\LCM_Disp”的程序时,想使用外部RAM进行仿真调试,在将ADS1.2中的“DebugInExram Settings…->Arm Linker -> Output -> Equivalent Command Line”的“-info totals -entry 0x8100000 -scatter .\src\mem_b.scf”改为“-info total

阿里云部署Java网站和微信开发调试心得技巧(上)

阿里云部署Java网站和微信开发调试心得技巧(上)本篇手记旨在帮助大家从0开始: 申请阿里云服务器 搭建出程序的执行环境 在服务器上发布并运行自己的web project 域名解析 微信测试号的申请与连接以获取微信用户信息全篇文章主要以如何去完成目标为主,因此会以流程的形式来展现,细节方面需要大家多多思考.其中文章的上集实现了1-4,文章的下集实现了5一.申请阿里云服务器(1)PC访问阿里云https://www.aliyun.com/,申请阿里云帐号(可以用您的支付宝帐号登录,因为支付宝帐号已

js断点调试心得

虽然网上已经有多的数不清的调试教程了,但仍然没有发现哪篇文章写的通俗易懂,索性自己尝试写写自己的一些使用习惯或者说是心得,希望对那些还不是很懂得使用断点调试的孩子有一些帮助(大神请无视~). 1.断点调试是啥?难不难? 断点调试其实并不是多么复杂的一件事,简单的理解无外呼就是打开浏览器,打开sources找到js文件,在行号上点一下罢了.操作起来似乎很简单,其实很多人纠结的是,是在哪里打断点?(我们先看一个断点截图,以chrome浏览器的断点为例) 步骤记住没? 用chrome浏览器打开页面 →

IE漏洞的调试心得

在调试漏洞的过程中,个人感觉最棘手的就是ie浏览器的漏洞和flash player的漏洞了.这里打算记录一下学习过程中的心得(主要是基于uaf类),以方便新人学习. 首先,ie漏洞与众不同的是,程序的执行流程是由攻击者控制的.poc中的js脚本反应到mshtml中的c++代码决定了程序的执行流程,所以对于ie漏洞来说仔细研究poc非常的关键.此外就是调试ie漏洞需要对ie本身有很强的了解,这也是我写这篇博文的动机,如果完全不清楚ie背后的机制,那么ie漏洞根本没法去调.

JS 断点调试心得

1.断点调试是啥?难不难? 断点调试其实并不是多么复杂的一件事,简单的理解无外呼就是打开浏览器,打开sources找到js文件,在行号上点一下罢了.操作起来似乎很简单,其实很多人纠结的是,是在哪里打断点?(我们先看一个断点截图,以chrome浏览器的断点为例) 步骤记住没? 用chrome浏览器打开页面 → 按f12打开开发者工具 → 打开Sources → 打开你要调试的js代码文件 → 在行号上单击一下,OK!恭喜你的处女断点打上了,哈哈~~ 2.断点怎么打才合适? 打断点操作很简单,核心的

网络广播系统调试心得

2011年底开始参与工厂级广播系统搭建,考虑未来工厂的扩建和管理的方便性,选择了网络广播系统,基于DSP的MAG5182主机为核心搭建网络广播系统,其实搭建过程及网络连接过程都很简单,但是如何避免车间内的回声是个难题,通过工厂广播系统的建设得出一个很好的解决方案. 最大的车间有500米长.200米宽.高约15米,由于钢结构的厂房设计,横排和竖排都是间隔24米的钢柱支撑(基本上大型厂房都是这个距离),根据钢柱间隔确定50瓦壁挂音箱,因为壁挂音箱的声场是扇形,而号角的声场是圆锥形状,能量较强,易产生

LCD屏背光驱动调试心得---血的教训

开发板:明远智睿MY-IMX6-EK140 内核源码:linux-3.14.52 背光驱动IC:MP3202 调光原理:通过开发板的核心板PWM4引脚控制MP3202的EN脚,输出不同的占空比从而达到输出平均电流的不同,这样就可以达到调节背光亮度的目的 调试过程: 1.从硬件图可以看出核心板的PWM4引脚连接到了背光驱动IC MP3202的EN脚,所以我们通过搜索PWM4来找设备树上的硬件节点 2.在明远智睿MY-IMX6-EK140设备树,arch/arm/boot/dts/myimx6ek1

FS44BOXII的调试心得

1.拿到板子,若要进行恢复出厂设置,则需要重新烧写BIOS程序,首先将RS232串口来传输数据,若电脑主机没有RS232串口接口,则可采用USB转串口的方式实现,本人即采用这种方式.在该过程中,注意设置USB的COM通讯方式,目前本人采用COM4,如图所示: 2.同理,设置好DWN.EXE中对应的COM通讯端口为COM4,如下图所示: 注意:因为BIOS程序是默认烧写位置是从FLASH的0地址单元的,而后继我们应用程序的烧写也会用到该地址单元,所以为了BIOS的程序不被应用程序覆盖,则需要在DN