Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL_Renderer改变引起的SDL_Texture失效问题 #3

Open
Kiritow opened this issue Apr 10, 2017 · 1 comment
Open

SDL_Renderer改变引起的SDL_Texture失效问题 #3

Kiritow opened this issue Apr 10, 2017 · 1 comment

Comments

@Kiritow
Copy link
Owner

Kiritow commented Apr 10, 2017

测试代码如下

#include <iostream>
using namespace std;

#include "MiniEngine.h"
#include "MiniEngine_Widget.h"
using namespace MiniEngine;

int AppMain()
{
    Window wnd("Title",1280,768);
    Renderer rnd=wnd.getRenderer();
    Texture t=rnd.loadTexture("1.png");
    Texture b=rnd.loadTexture("2.png");
    rnd.clear();
    rnd.copyFullFill(t);
    rnd.update();
    while(1)
    {
        SDL_Event e;
        SDL_WaitEvent(&e);
        if(e.type==SDL_MOUSEBUTTONDOWN) break;
    }
    cout<<"Changed"<<endl;
    wnd.setRenderer(RendererType::Accelerated);
    Renderer nrnd=wnd.getRenderer();
    cout<<rnd.isReady()<<" "<<nrnd.isReady()<<endl;

    nrnd.clear();
    nrnd.update();
    ErrorViewer ss;
    ss.fetch();
    cout<<ss.what()<<endl;
    while(1)
    {
        SDL_Event e;
        SDL_WaitEvent(&e);
        if(e.type==SDL_MOUSEBUTTONDOWN) break;
    }
    nrnd.clear();
    nrnd.copyFullFill(b);
    nrnd.update();
    ss.fetch();
    cout<<ss.what()<<endl;
    cout<<"Printed"<<endl;
    while(1)
    {
        SDL_Event e;
        SDL_WaitEvent(&e);
        if(e.type==SDL_MOUSEBUTTONDOWN) break;
    }

    return 0;
}

根据当前情况,nrnd的建立会导致rnd的失效,此时rnd渲染的t和b都处于无效状态(Invalid Texture).
解决这个问题可以将Texture中的指针改为weak_ptr,并将真正的Texture放入Window类中. 但是这样的话又不能在Texture超出作用域的时候自动释放(因为都保存在Window里了),这样很有可能引起内存暴涨...

@Kiritow Kiritow added the bug label Apr 10, 2017
Kiritow added a commit that referenced this issue Apr 20, 2017
Fix issue #3:
class Texture has a shared_ptr to weak_ptr. The weak_ptr observes a
shared_ptr in a list in class Window.
When Window::setRenderer is called, Textures will be released and the
previous renderer is also release. Then a new renderer is created. User
should reload textures by themselves.
@Kiritow
Copy link
Owner Author

Kiritow commented Apr 20, 2017

这个问题在这个提交中被解决~
将真正的SDL_Texture存储在Window中,在Texture中只保留一个指向该shared_ptr的weak_ptr,使用shared_ptr包装保证Texture能够被自由复制。在所有Texture自然超出作用域的时候,Texture此时默认失效,调用Window中的_deleteTexture_SP进行真正的删除.(SDL_Texture的删除操作在创建智能指针时已被指定,在方法Window::_newTexture_Raw中)
不得不在Texture和Renderer中添加Window的地址信息,为防止问题将Window设置为不可拷贝的(noncopyable)

@Kiritow Kiritow removed the bug label Apr 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant