From fe9252bd5eaa70c0b98203049d9bf38b20f93ca6 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Wed, 14 Nov 2012 20:13:31 +0000 Subject: First attempt at optimising the redraw of frame scrolls. some of these calculations are wrong. --- amiga/gui.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ desktop/browser.c | 32 +++++++++++++++++++++++++ desktop/browser.h | 11 +++++++++ desktop/browser_private.h | 4 ++++ desktop/frames.c | 44 ++++++++++++++++++++++++++++++---- desktop/gui.h | 13 ++++++++++ 6 files changed, 161 insertions(+), 4 deletions(-) diff --git a/amiga/gui.c b/amiga/gui.c index 293379283..d0729939e 100755 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -1036,6 +1036,36 @@ void ami_update_quals(struct gui_window_2 *gwin) } } +bool ami_ns_to_screen_coords(struct gui_window_2 *gwin, int *x, int *y) +{ + ULONG xs, ys; + int ns_x = *x; + int ns_y = *y; + struct IBox *bbox; + + GetAttr(SPACE_AreaBox, (Object *)gwin->objects[GID_BROWSER], (ULONG *)&bbox); + + ns_x *= gwin->bw->scale; + ns_y *= gwin->bw->scale; + + if((ns_x < 0) || (ns_x > bbox->Width) || (ns_y < 0) || (ns_y > bbox->Height)) + return false; + + ami_get_hscroll_pos(gwin, (ULONG *)&xs); + ami_get_vscroll_pos(gwin, (ULONG *)&ys); + + ns_x += xs; + ns_y += ys; + + ns_x += bbox->Left; + ns_y += bbox->Top; + + *x = ns_x; + *y = ns_y; + + return true; +} + bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y, int mouse_x, int mouse_y) { @@ -3565,6 +3595,37 @@ void ami_do_redraw(struct gui_window_2 *g) g->new_content = false; } +bool gui_window_copy_box(struct gui_window *g, const struct rect *rect, int x, int y) +{ + struct IBox *bbox; + struct gui_window_2 *gwin = g->shared; + int src_x = rect->x0; + int src_y = rect->y0; + int dest_x = x; + int dest_y = y; + int src_x1 = rect->x1; + int src_y1 = rect->y1; +printf("%ld,%ld,%ld,%ld,%ld,%ld\n", src_x, src_y, src_x1, src_y1, dest_x, dest_y); + if(ami_ns_to_screen_coords(gwin, &src_x, &src_y) == false) return false; + if(ami_ns_to_screen_coords(gwin, &src_x1, &src_y1) == false) return false; + if(ami_ns_to_screen_coords(gwin, &dest_x, &dest_y) == false) return false; +printf("== %ld,%ld,%ld,%ld,%ld,%ld\n", src_x, src_y, src_x1, src_y1, dest_x, dest_y); + + BltBitMapTags(BLITA_SrcType, BLITT_RASTPORT, + BLITA_Source, gwin->win->RPort, + BLITA_SrcX, src_x, + BLITA_SrcY, src_y, + BLITA_DestType, BLITT_RASTPORT, + BLITA_Dest, gwin->win->RPort, + BLITA_DestX, dest_x, + BLITA_DestY, dest_y, + BLITA_Width, src_x1 - src_x, + BLITA_Height, src_y1 - src_y, + TAG_DONE); + + return true; +} + void ami_refresh_window(struct gui_window_2 *gwin) { /* simplerefresh only */ diff --git a/desktop/browser.c b/desktop/browser.c index 89484609e..0ecb0ac77 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -1947,6 +1947,38 @@ void browser_window_update_box(struct browser_window *bw, struct rect *rect) } +/* exported interface, documented in browser.h */ +void browser_window_copy_box(struct browser_window *bw, struct rect *rect, int x, int y) +{ + int pos_x; + int pos_y; + struct browser_window *top; + + assert(bw); + + if (bw->window != NULL) { + /* Front end window */ + if(gui_window_copy_box(bw->window, rect, x, y) == false) { + gui_window_update_box(bw->window, rect); + } + } else { + /* Core managed browser window */ + browser_window_get_position(bw, true, &pos_x, &pos_y); + + top = browser_window_get_root(bw); + + rect->x0 += pos_x / bw->scale; + rect->y0 += pos_y / bw->scale; + rect->x1 += pos_x / bw->scale; + rect->y1 += pos_y / bw->scale; + + if(gui_window_copy_box(top->window, rect, x + pos_x, y + pos_y) == false) { + gui_window_update_box(top->window, rect); + } + } +} + + /** * Stop all fetching activity in a browser window. * diff --git a/desktop/browser.h b/desktop/browser.h index f3c68fa09..b0965e1c3 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -94,6 +94,17 @@ void browser_window_reformat(struct browser_window *bw, bool background, void browser_window_set_scale(struct browser_window *bw, float scale, bool all); float browser_window_get_scale(struct browser_window *bw); +/** + * Copy an area of the browser window to the given x,y co-ordinates. + * Source and destination may overlap. + * + * \param bw browser window + * \param rect area to copy + * \param x x-coordinate of destination to copy to + * \param y y-coordinate of destination to copy to + */ +void browser_window_copy_box(struct browser_window *bw, struct rect *rect, int x, int y); + /** * Get access to any content, link URLs and objects (images) currently * at the given (x, y) coordinates. diff --git a/desktop/browser_private.h b/desktop/browser_private.h index 91372acc3..d008d887a 100644 --- a/desktop/browser_private.h +++ b/desktop/browser_private.h @@ -110,6 +110,10 @@ struct browser_window { struct scrollbar *scroll_x; /**< Horizontal scroll. */ struct scrollbar *scroll_y; /**< Vertical scroll. */ + + /** previous scroll offsets */ + int prev_scroll_x; + int prev_scroll_y; /** scale of window contents */ float scale; diff --git a/desktop/frames.c b/desktop/frames.c index cc2cabfd2..4de33cb4f 100644 --- a/desktop/frames.c +++ b/desktop/frames.c @@ -64,13 +64,49 @@ void browser_window_scroll_callback(void *client_data, html_redraw_a_box(bw->parent->current_content, bw->box); } else { struct rect rect; + struct rect copyrect; + int dest_x = 0; + int dest_y = 0; + int cur_x = scrollbar_get_offset(bw->scroll_x); + int cur_y = scrollbar_get_offset(bw->scroll_y); + + if(cur_x > bw->prev_scroll_x) { + copyrect.x0 = cur_x; + copyrect.x1 = copyrect.x0 + bw->width - (cur_x - bw->prev_scroll_x); + dest_x = bw->prev_scroll_x; + + rect.x0 = copyrect.x0; + rect.x1 = copyrect.x0 + bw->width - (cur_x - bw->prev_scroll_x); + } else { + copyrect.x0 = bw->prev_scroll_x; + copyrect.x1 = copyrect.x0 + bw->width - (bw->prev_scroll_x - cur_x); + dest_x = cur_x; + + rect.x0 = cur_x; + rect.x1 = cur_x + bw->width - (bw->prev_scroll_x - cur_x); + } - rect.x0 = scrollbar_get_offset(bw->scroll_x); - rect.y0 = scrollbar_get_offset(bw->scroll_y); - rect.x1 = rect.x0 + bw->width; - rect.y1 = rect.y0 + bw->height; + if(cur_y > bw->prev_scroll_y) { + copyrect.y0 = cur_y; + copyrect.y1 = copyrect.y0 + bw->height - (cur_y - bw->prev_scroll_y); + dest_y = bw->prev_scroll_y; + + rect.y0 = copyrect.y0; + rect.y1 = copyrect.y0 + bw->height - (cur_y - bw->prev_scroll_y); + } else { + copyrect.y0 = bw->prev_scroll_y; + copyrect.y1 = copyrect.y0 + bw->height - (bw->prev_scroll_y - cur_y); + dest_y = cur_y; + + rect.y0 = cur_y; + rect.y1 = cur_y + bw->height - (bw->prev_scroll_y - cur_y); + } + browser_window_copy_box(bw, ©rect, dest_x, dest_y); browser_window_update_box(bw, &rect); + + bw->prev_scroll_x = scrollbar_get_offset(bw->scroll_x); + bw->prev_scroll_y = scrollbar_get_offset(bw->scroll_y); } break; case SCROLLBAR_MSG_SCROLL_START: diff --git a/desktop/gui.h b/desktop/gui.h index 48684c3c5..551848586 100644 --- a/desktop/gui.h +++ b/desktop/gui.h @@ -79,6 +79,19 @@ void gui_window_set_title(struct gui_window *g, const char *title); void gui_window_redraw_window(struct gui_window *g); void gui_window_update_box(struct gui_window *g, const struct rect *rect); + +/** + * Copy an area of the displayed gui_window to the co-ordinates + * specified by x,y. NB: source and destination may overlap. + * + * \param g The window to perform the copy on. + * \param rect The rectangle to copy. + * \param x The X co-ordinate to copy to. + * \param y The Y co-ordinate to copy to. + * \return true if the region could be copied, false otherwise. + */ +bool gui_window_copy_box(struct gui_window *g, const struct rect *rect, int x, int y); + bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy); void gui_window_set_scroll(struct gui_window *g, int sx, int sy); void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, -- cgit v1.2.3