Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Dirty rectangle woes

Dirty rectangle woes

Scheduled Pinned Locked Moved The Lounge
graphicsc++designcsharpcss
17 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Daniel Pfeffer

    If you keep all screen objects sorted in Z-order, you should be able to determine which object(s) overlap others, and therefore draw only the object at the top of the Z-order for that area. There are many books / articles / ... describing the algorithm, most developed when screen I/O was much slower than it is today. They should therefore be suitable for slow devices like your IoT screens.

    Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

    H Offline
    H Offline
    honey the codewitch
    wrote on last edited by
    #7

    Yeah, my controls container is sorted in z-order like Winforms. One wrinkle is I have a configurable or otherwise variable size bitmap to write to. I then send that bitmap to the display. Since the bitmap is smaller than the display this must be repeated several times in order to render a full screen. This will also in some cases, require a control to draw more than once during a render. It's really complicating things.

    To err is human. Fortune favors the monsters.

    D 1 Reply Last reply
    0
    • H honey the codewitch

      Yeah, my controls container is sorted in z-order like Winforms. One wrinkle is I have a configurable or otherwise variable size bitmap to write to. I then send that bitmap to the display. Since the bitmap is smaller than the display this must be repeated several times in order to render a full screen. This will also in some cases, require a control to draw more than once during a render. It's really complicating things.

      To err is human. Fortune favors the monsters.

      D Offline
      D Offline
      Daniel Pfeffer
      wrote on last edited by
      #8

      "Banding" (or perhaps "Tiling" in your case) is also a solved problem - you treat the area as a viewport. Draw all visible objects (according to Z-order), but before drawing - clip them against the viewport window. If the object is totally outside the viewport, your work is done. You could combine this with the Z-order by placing the viewport as the "highest" object in your Z-order, so anything hidden by it doesn't need drawing. All you need to do is move the viewport around the display until all parts have been rendered.

      Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

      H 1 Reply Last reply
      0
      • D Daniel Pfeffer

        "Banding" (or perhaps "Tiling" in your case) is also a solved problem - you treat the area as a viewport. Draw all visible objects (according to Z-order), but before drawing - clip them against the viewport window. If the object is totally outside the viewport, your work is done. You could combine this with the Z-order by placing the viewport as the "highest" object in your Z-order, so anything hidden by it doesn't need drawing. All you need to do is move the viewport around the display until all parts have been rendered.

        Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

        H Offline
        H Offline
        honey the codewitch
        wrote on last edited by
        #9

        I get that. But that's a naive approach and could potentially perform a lot better than that, particularly when combined with dirty rects. An example. My window isn't fixed size. Let's say I have 100 pixels. I can arrange that in any rectangle that's <= 100 in area. Because of that, I can potentially avoid drawing controls twice or more, which you'd have to do in a lot of cases with a fixed window because controls will overlap more than one the window/viewport. I make the viewport the shape of what I'm drawing. Or so I think, but it's one of those things I can't refine and verify without trying to code it.

        To err is human. Fortune favors the monsters.

        D 1 Reply Last reply
        0
        • H honey the codewitch

          I'm building a control library in C++ that sits on top of my IoT graphics library and provides interactive user interface elements, kind of like winforms, but less elaborate. I hate dirty rectangle finding routines. I've never been able to quite wrap my head around them, and to the degree that I can, what I come up with is almost certainly a naïve approach and not optimally performant. 1. Go through a list of controls. Of the controls that are visible and need to be redrawn. Find overlapping controls. If they overlap then you want to draw them both at once so you don't send to the display twice. Making an overlap list is way more difficult than I want it to be. But basically we create buckets of controls. 2. For each bucket of overlapping controls: 2a. try to create a bitmap that's large enough to hold all the overlapping controls in the bucket 2b. if you can't then split the bucket into several rectangles, and draw the controls more than once if need be. (more difficult than it sounds) 2c. call the render method on each control in the bucket, and then call the screen render callback to send that bitmap to the appropriate position on the display I can articulate the above, but implementing it is another matter. With the full STL it would be much easier, but I don't necessarily have access to it, so I have my own simple vector library. Absolutely frustrating. I'll solve it - I already know how, more or less. It's just a matter of stewing on it, creating the code, testing and optimizing it. In some ways I'm close - at least in terms of design - but beyond that may as well be the moon. Edit: The above isn't quite right algorithmically, and I've since adjusted things.

          To err is human. Fortune favors the monsters.

          M Offline
          M Offline
          megaadam
          wrote on last edited by
          #10

          What if... you had no overlapping controls? This would ofc require extra work on layout, and splitting the draw rects of some controls into more than one rect (or even splitting them into more controls). I realise that at a late stage of a project, this is hardly feasible, so it might be more of a hypothetical question.

          "If we don't change direction, we'll end up where we're going"

          H 1 Reply Last reply
          0
          • M megaadam

            What if... you had no overlapping controls? This would ofc require extra work on layout, and splitting the draw rects of some controls into more than one rect (or even splitting them into more controls). I realise that at a late stage of a project, this is hardly feasible, so it might be more of a hypothetical question.

            "If we don't change direction, we'll end up where we're going"

            H Offline
            H Offline
            honey the codewitch
            wrote on last edited by
            #11

            This library is too general purpose to impose those kinds of layout restrictions. It would be very difficult to use if I imposed the limitation that controls could not overlap.

            To err is human. Fortune favors the monsters.

            M 1 Reply Last reply
            0
            • H honey the codewitch

              This library is too general purpose to impose those kinds of layout restrictions. It would be very difficult to use if I imposed the limitation that controls could not overlap.

              To err is human. Fortune favors the monsters.

              M Offline
              M Offline
              megaadam
              wrote on last edited by
              #12

              Yeah, I am not exactly surprised. But I am surprised though as you seem to be answering all sorts of posts 24/7, if you don't mind my asking, do you ever sleep?

              "If we don't change direction, we'll end up where we're going"

              H 1 Reply Last reply
              0
              • M megaadam

                Yeah, I am not exactly surprised. But I am surprised though as you seem to be answering all sorts of posts 24/7, if you don't mind my asking, do you ever sleep?

                "If we don't change direction, we'll end up where we're going"

                H Offline
                H Offline
                honey the codewitch
                wrote on last edited by
                #13

                I sleep 4 hours at a time, so I'm up a lot, and at strange hours.

                To err is human. Fortune favors the monsters.

                1 Reply Last reply
                0
                • H honey the codewitch

                  I'm building a control library in C++ that sits on top of my IoT graphics library and provides interactive user interface elements, kind of like winforms, but less elaborate. I hate dirty rectangle finding routines. I've never been able to quite wrap my head around them, and to the degree that I can, what I come up with is almost certainly a naïve approach and not optimally performant. 1. Go through a list of controls. Of the controls that are visible and need to be redrawn. Find overlapping controls. If they overlap then you want to draw them both at once so you don't send to the display twice. Making an overlap list is way more difficult than I want it to be. But basically we create buckets of controls. 2. For each bucket of overlapping controls: 2a. try to create a bitmap that's large enough to hold all the overlapping controls in the bucket 2b. if you can't then split the bucket into several rectangles, and draw the controls more than once if need be. (more difficult than it sounds) 2c. call the render method on each control in the bucket, and then call the screen render callback to send that bitmap to the appropriate position on the display I can articulate the above, but implementing it is another matter. With the full STL it would be much easier, but I don't necessarily have access to it, so I have my own simple vector library. Absolutely frustrating. I'll solve it - I already know how, more or less. It's just a matter of stewing on it, creating the code, testing and optimizing it. In some ways I'm close - at least in terms of design - but beyond that may as well be the moon. Edit: The above isn't quite right algorithmically, and I've since adjusted things.

                  To err is human. Fortune favors the monsters.

                  B Offline
                  B Offline
                  BillWoodruff
                  wrote on last edited by
                  #14

                  if ... the controls are not movable by the user, and, the graphic context is not having resolution changes ... can you save the extent when the controls are instantiated ?

                  «The mind is not a vessel to be filled but a fire to be kindled» Plutarch

                  H 1 Reply Last reply
                  0
                  • H honey the codewitch

                    I get that. But that's a naive approach and could potentially perform a lot better than that, particularly when combined with dirty rects. An example. My window isn't fixed size. Let's say I have 100 pixels. I can arrange that in any rectangle that's <= 100 in area. Because of that, I can potentially avoid drawing controls twice or more, which you'd have to do in a lot of cases with a fixed window because controls will overlap more than one the window/viewport. I make the viewport the shape of what I'm drawing. Or so I think, but it's one of those things I can't refine and verify without trying to code it.

                    To err is human. Fortune favors the monsters.

                    D Offline
                    D Offline
                    Daniel Pfeffer
                    wrote on last edited by
                    #15

                    OK, combine with dirty rectangles: 1. Calculate a bounding box for all the "dirty rectangles". 2. Position the viewport so that a maximal (or at least a non-zero) area of "dirty rectangles" is visible. Note that you may ignore anything outside the bounding box - it doesn't need redrawing. 3. Redraw the visible parts of any dirty rectangles (i.e. those inside the viewport). 4. Mark any fully visible "dirty rectangles" as "clean". 5. Clip any partially-visible "dirty rectangles" to the exterior of the viewport (i.e. what remains is the part that is not visible in the viewport). Note that this may involve splitting a clipped "dirty rectangle" into a few subregions, each rectangular, e.g. if a rectangle overlaps more than one side of the viewport. 6. If any "dirty rectangles" remain, go to step 1. This will require controls in clipped "dirty rectangles" to be drawn more than once, but there is no way around this. An algorithm for positioning the viewport is left for the alert reader. :) Note that this algorithm requires access only to the "dirty rectangle" list, so it should be quite fast.

                    Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

                    H 1 Reply Last reply
                    0
                    • D Daniel Pfeffer

                      OK, combine with dirty rectangles: 1. Calculate a bounding box for all the "dirty rectangles". 2. Position the viewport so that a maximal (or at least a non-zero) area of "dirty rectangles" is visible. Note that you may ignore anything outside the bounding box - it doesn't need redrawing. 3. Redraw the visible parts of any dirty rectangles (i.e. those inside the viewport). 4. Mark any fully visible "dirty rectangles" as "clean". 5. Clip any partially-visible "dirty rectangles" to the exterior of the viewport (i.e. what remains is the part that is not visible in the viewport). Note that this may involve splitting a clipped "dirty rectangle" into a few subregions, each rectangular, e.g. if a rectangle overlaps more than one side of the viewport. 6. If any "dirty rectangles" remain, go to step 1. This will require controls in clipped "dirty rectangles" to be drawn more than once, but there is no way around this. An algorithm for positioning the viewport is left for the alert reader. :) Note that this algorithm requires access only to the "dirty rectangle" list, so it should be quite fast.

                      Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

                      H Offline
                      H Offline
                      honey the codewitch
                      wrote on last edited by
                      #16

                      Thanks for this. I'm a bit too tired to grok it fully but I've copied it to notepad for later perusal. :thumbsup:

                      To err is human. Fortune favors the monsters.

                      1 Reply Last reply
                      0
                      • B BillWoodruff

                        if ... the controls are not movable by the user, and, the graphic context is not having resolution changes ... can you save the extent when the controls are instantiated ?

                        «The mind is not a vessel to be filled but a fire to be kindled» Plutarch

                        H Offline
                        H Offline
                        honey the codewitch
                        wrote on last edited by
                        #17

                        The controls are moveable but they usually will not be moved, so it may be possible to cache the results of at least part of what I'm computing. It also might be beneficial. However, the biggest bottleneck is display I/O and the biggest constraint I have is memory, so really the part I have to get right first is how to draw to the display the least amount of times using a relatively small bitmap as my draw surface, and rendering over and over as I move through different parts of the display. To complicate matters the size of the bitmap isn't necessary to be fixed. Basically if I allocate 100 pixels, I can create a bitmap of any size that's a total area of 100 pixels or less, so through optimization, I can potentially avoid redrawing controls more than once. However, these things need to be tied together so it works properly. I can't just add the second optimization after the fact. I'd have to rewrite all of it. That's the primary challenge I'm facing.

                        To err is human. Fortune favors the monsters.

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups