Page 1 of 1

Double buffer problem

Posted: Fri Nov 01, 2019 1:30 am
by Kamal123
Hi,
First of all, sorry for my bad english

I am facing a problem with double buffer.. my double buffer doesn't work properly... It produces black rectangle on the screen..while I want an white rectangle to be drawn on the screen of some size....but my double buffer fills the entire screen with some cracked line!!...

Plz help... :(

Re: Double buffer problem

Posted: Fri Nov 01, 2019 2:19 am
by Kamal123
Kamal123 wrote:Hi,
First of all, sorry for my bad english

I am facing a problem with double buffer.. my double buffer doesn't work properly... It produces black rectangle on the screen..while I want an white rectangle to be drawn on the screen of some size....but my double buffer fills the entire screen with some cracked line!!...

Plz help... :(
Don't ignore please...

Re: Double buffer problem

Posted: Fri Nov 01, 2019 4:19 am
by nullplan
Kamal123 wrote:
Kamal123 wrote:Hi,
First of all, sorry for my bad english

I am facing a problem with double buffer.. my double buffer doesn't work properly... It produces black rectangle on the screen..while I want an white rectangle to be drawn on the screen of some size....but my double buffer fills the entire screen with some cracked line!!...

Plz help... :(
Don't ignore please...
Bad English is not an issue. Inability to ask a question and impatience are, however.

Normal response time for a forum post is 24 hours. It just takes some time for everyone to have read it, and formulated a response. One hour? Jesus, I'm not on this platform 24/7. I am not alerted (nor do I wish to be) when new stuff is posted. This isn't reddit. I have a life outside of this forum.

Second, you have failed to ask a question that can be answered. Where's your code? What are you working with? Before you can get to a double buffer, you must already have video output working. How do you do that? Just VGA? What measures have you taken to debug the issue? My glass ball is currently being cleaned, so I can't divine the answer to these questions.

Re: Double buffer problem

Posted: Fri Nov 01, 2019 6:14 am
by Kamal123
nullplan wrote:
Kamal123 wrote:
Kamal123 wrote:Hi,
First of all, sorry for my bad english

I am facing a problem with double buffer.. my double buffer doesn't work properly... It produces black rectangle on the screen..while I want an white rectangle to be drawn on the screen of some size....but my double buffer fills the entire screen with some cracked line!!...

Plz help... :(
Don't ignore please...
Bad English is not an issue. Inability to ask a question and impatience are, however.

Normal response time for a forum post is 24 hours. It just takes some time for everyone to have read it, and formulated a response. One hour? Jesus, I'm not on this platform 24/7. I am not alerted (nor do I wish to be) when new stuff is posted. This isn't reddit. I have a life outside of this forum.

Second, you have failed to ask a question that can be answered. Where's your code? What are you working with? Before you can get to a double buffer, you must already have video output working. How do you do that? Just VGA? What measures have you taken to debug the issue? My glass ball is currently being cleaned, so I can't divine the answer to these questions.



Thanks for correcting me. Actually I am new to this forum. I use vesa lfb for video output. and it works fine.. when i don't use double buffer, it works fine.... but when i initialize double buffer then the screen get corrupted with black color..with some white line..


Where can be the mistake??


My vesa resolution is 1024x720 and I use virtual box for emulation.


my code...

Code: Select all

void rect_filled1(int x, int y, int w, int h, uint32_t col, uint32_t *data){
	VideoTerminal terminal = GetTerminal();
	uint32_t* lfb = (uint32_t*)data;
	for(uint32_t k = 0; k < h; k++)
		for(uint32_t j = 0; j < w; j++)
			lfb[(w+x) + (h+y) *terminal.height] = col;
}

void Update(uint32_t *data){
	uint32_t *lfb = (uint32_t*)0x1000000;
	for(int i = 0; i < 1024*720; i++){
        lfb[i] = data[i];
	}
}

void InitializeBackBuffer(){
	VideoTerminal vt = GetTerminal();
		uintptr_t*e = (uintptr_t*)PmmngrAllocBlock();
	 size_t BytesToMap = vt.BytesPerScanLine * vt.height/4096;
	 for(int i = 0; i <= BytesToMap; i++){
		
	  VmmngrMap((void*)(e + (i*4096)),(void*)(0xF00000000 + (i*4096)));
	 }

	 back = (uint32_t*)0xF00000000;
}

void CreateFrame(int x, int y, int width, int height){
	uint32_t buf = (uint32_t)0xF00000000;
	rect_filled1(x,y,width,height,rgb(223,228,230), (uint32_t*)buf);
	Update((uint32_t*)buf);
	//VideoDrawLine(x,y,x-width,y,rgb(12,22,32));

}


void Main(Multiboot_info *info){
      InitializeVideo(info);

      InitializeBackBuffer();    

      CreateFrame(10,20,300,100);
 }

Re: Double buffer problem

Posted: Fri Nov 01, 2019 11:02 am
by Schol-R-LEA
As a piece of advice before I address your question, I would recommend giving a link to your online repo, so we can go over any code you haven't posted here. I would even go so far as to suggest putting the link in your .sig for the forum, so it will be available whenever you post here.

If you don't have a repo yet, then I strongly urge you to drop everything else and set one up immediately, for this project and any other project you might be working on, no matter how small. I cannot stress enough how important version control is, for a variety of reasons including having an offsite backup of your code, as an audit trail for your changes, and as a way to make it easier to experiment with various changes to your code while ensuring that the main branch is untouched.

If nothing else, it makes it easy to let other see your code without having to post large code sections to the forum.

It doesn't really matter which VCS you use (whether it is Subversion, GIT, Bazaar, Mercurial, Team Foundation Server, whatever) or host (GitHub, Gitlab, CloudForge, etc.). What is important is to have some system in place. Most of the major project hosts will serve FOSS projects for free.

Sorry for being so strident about this, but it is something which is too valuable a tool and a resource not to use.

Second, note that the forum software (phpBB, and sadly, a rather ancient version at that) does not retain text/code formatting by default - something which you will find is the case for nearly all message board software, though how they work around it to allow code samples to be posted varies. This is a common misunderstanding for newcomers to fora in general, so no harm, no foul.

In the case of phpBB, it uses what are called 'BBcode tags', which resemble HTML tags but use square brackets instead of angle brackets, and accept a different set of tags from base HTML. in this case, the [ code ] tag (without the spaces) opens a code section, and the [ /code ] tag (again, with the spaces removed) closes it. There is a 'code' button at the top over the editing window which you can use to add these automatically.

Unfortunately, the current forum doesn't have the modules to support color highlighting installed. Also, the forum sometimes has problems handling tabs in a helpful fashion, so it is often better to use bare spaces instead. That having been said, here is your code suitably formatted (though not, as I said, highlighted):

Code: Select all

void rect_filled1(int x, int y, int w, int h, uint32_t col, uint32_t *data) {
    VideoTerminal terminal = GetTerminal();
    uint32_t* lfb = (uint32_t*)data;
    for(uint32_t k = 0; k < h; k++)
        for(uint32_t j = 0; j < w; j++)
            lfb[(w+x) + (h+y) *terminal.height] = col;
}

void Update(uint32_t *data) {
    uint32_t *lfb = (uint32_t*)0x1000000;
    for(int i = 0; i < 1024*720; i++) {
        lfb[i] = data[i];
    }
}

void InitializeBackBuffer() {
    VideoTerminal vt = GetTerminal();
    uintptr_t *e = (uintptr_t*)PmmngrAllocBlock();
    size_t BytesToMap = vt.BytesPerScanLine * vt.height/4096;
    for(int i = 0; i <= BytesToMap; i++) {
        VmmngrMap((void*)(e + (i*4096)),(void*)(0xF00000000 + (i*4096)));
    }
    back = (uint32_t*)0xF00000000;
}

void CreateFrame(int x, int y, int width, int height) {
    uint32_t buf = (uint32_t)0xF00000000;
    rect_filled1(x,y,width,height,rgb(223,228,230), (uint32_t*)buf);
    Update((uint32_t*)buf);
    //VideoDrawLine(x,y,x-width,y,rgb(12,22,32));
}

void Main(Multiboot_info *info) {
    InitializeVideo(info);

    InitializeBackBuffer();    

    CreateFrame(10,20,300,100);
 }
Given this now, we can see the structure of the code clearly, and I notice a few things right away. First, in the code as given, you are jumping into initializing the video immediately, rather than doing all of the other housekeeping one would normally tackle at this point (setting up the OS's own GDT, LDTs, and IDT to replace the default one from the bootloader, setting up a scheduler, etc.). Now, it is likely that all of this was done in the multiboot entry code, so I doubt it is relevant - especially since you stated that it was working correctly with double buffering disabled - but it does stand out. While we don't actually need to the full startup code in front of us, knowing where we could view it would help. This is part of why I was so adamant about having an online repo which you could link to us.

What we do need, or at least what would be a significant help for us, is the working code, so we can compare them and try to work out why the double-buffering version fails. If you could please post the relevant functions from the working version (the ones which different from that above), or even just explain how they differ, it would help a great deal.

Some more things that I note are:
  • You have both the address of the linear frame buffer and the back buffer in the code as 'magic numbers', that is to say, numeric constants. While you do assign both to local variables, this is one place where a named global constant may be better, even if you just end up assigning to the local variable in the same manner.
  • On a related note, I am not clear what the three uses of '4096' in InitializeBackBuffer() are in reference to, or even if they are for the same or related purposes or not. In the first instance, you divide the terminal height (presumably 720 in this case, though you clearly intend it to work with any height of terminal), which (assuming that vt.height directly corresponds to the screen resolution, which I suppose it might not) is going to present a significant problem for an integer division. Also, why 0x1000 in the first place? I don't know enough about your particular terminal structure and representation to see the purpose of this, yet. Similar questions arise where you use the same constant in the virtual memory mapping call, though I get the impression that these do not actually have the same meaning as in the previous line. Could you explain these to us a bit, so we could see what the intent was?
  • In CreateFrame(), was there any specific reason why you declared buf as a uint32_t, when both of the subsequent uses for it are cast to uint32_t*? It just seems to me that simply declaring it as uint32_t* would have been easier, but I don't know if there was some reason not to that I am missing.
I know that this is a relatively shallow analysis, but I really would need to see more of the code to say more, especially the difference between this and the working single-buffer code.

EDIT: Two quick questions, by any chance was the line covering terminal height meant to read:

Code: Select all

    size_t BytesToMap = (vt.BytesPerScanLine * vt.height)/4096;
that is to say, dividing the product of the bytes per scan line and the height by 0x1000, rather than just the height? Also, is the 0x1000 in the later line

Code: Select all

        VmmngrMap((void*)(e + (i*4096)),(void*)(0xF00000000 + (i*4096)));
a memory page size, and if so, are you certain that you are using the 32-bit protected mode default 4KiB pages, as opposed to the larger 4MiB pages (which can be used in p-mode depending on the setting for the page tables, and IIUC are pretty much standard for Long Mode)?

Re: Double buffer problem

Posted: Fri Nov 01, 2019 11:27 am
by JAAman
please use code tags, and refrain from using colors in your posts

I have edited your post to fix this issue this time, but in the future please remember to use code tags

Re: Double buffer problem

Posted: Sun Nov 03, 2019 8:44 am
by Schol-R-LEA
Kamal123: Just out of curiosity, were you able to make any headway on this problem, and if so, what solutions were you able to come up with? I know that my analysis was fairly limited (for reasons I explained in my previous post), but I was wondering if any of that helped at all.

Re: Double buffer problem

Posted: Mon Nov 04, 2019 11:53 am
by Kamal123
Schol-R-LEA wrote:Kamal123: Just out of curiosity, were you able to make any headway on this problem, and if so, what solutions were you able to come up with? I know that my analysis was fairly limited (for reasons I explained in my previous post), but I was wondering if any of that helped at all.

Yes.. I solved the problem.. actually, the problem was that-- Instead of writing the rectangle pixels to the buffer B I wrote to buffer A...that is why I noticed strange in the screen.. now I can write to buffer B and update it to buffer A..
And also thank you guys for correcting me in posting codes.. from now onwards I will follow the rules.
And sorry for late reply..

And yes, it helped me for further improvement...