Double buffer problem

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
Kamal123
Member
Member
Posts: 99
Joined: Fri Nov 01, 2019 1:17 am

Double buffer problem

Post 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... :(
Kamal123
Member
Member
Posts: 99
Joined: Fri Nov 01, 2019 1:17 am

Re: Double buffer problem

Post 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...
nullplan
Member
Member
Posts: 1769
Joined: Wed Aug 30, 2017 8:24 am

Re: Double buffer problem

Post 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.
Carpe diem!
Kamal123
Member
Member
Posts: 99
Joined: Fri Nov 01, 2019 1:17 am

Re: Double buffer problem

Post 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);
 }
Attachments
Frame.cpp
this is the window frame code ..
(1.57 KiB) Downloaded 98 times
this is the result when I use double buffer
this is the result when I use double buffer
Last edited by JAAman on Fri Nov 01, 2019 11:10 am, edited 1 time in total.
Reason: adding code tags and removing text coloring
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: Double buffer problem

Post 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)?
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: Double buffer problem

Post 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
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: Double buffer problem

Post 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.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Kamal123
Member
Member
Posts: 99
Joined: Fri Nov 01, 2019 1:17 am

Re: Double buffer problem

Post 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...
Post Reply