Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: chrome/browser/renderer_host/backing_store_posix.cc

Issue 21050: POSIX: Backing store scrolling. (Closed)
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/renderer_host/backing_store.h" 5 #include "chrome/browser/renderer_host/backing_store.h"
6 6
7 #include "base/logging.h"
8 #include "skia/ext/platform_canvas.h"
9 #include "skia/include/SkBitmap.h"
10 #include "skia/include/SkCanvas.h"
11
7 BackingStore::BackingStore(const gfx::Size& size) 12 BackingStore::BackingStore(const gfx::Size& size)
8 : size_(size) { 13 : size_(size) {
9 if (!canvas_.initialize(size.width(), size.height(), true)) 14 if (!canvas_.initialize(size.width(), size.height(), true))
10 SK_CRASH(); 15 SK_CRASH();
11 } 16 }
12 17
13 BackingStore::~BackingStore() { 18 BackingStore::~BackingStore() {
14 } 19 }
15 20
16 bool BackingStore::PaintRect(base::ProcessHandle process, 21 bool BackingStore::PaintRect(base::ProcessHandle process,
17 BitmapWireData bitmap, 22 BitmapWireData bitmap,
18 const gfx::Rect& bitmap_rect) { 23 const gfx::Rect& bitmap_rect) {
19 if (bitmap.width() != bitmap_rect.width() || 24 if (bitmap.width() != bitmap_rect.width() ||
20 bitmap.height() != bitmap_rect.height() || 25 bitmap.height() != bitmap_rect.height() ||
21 bitmap.config() != SkBitmap::kARGB_8888_Config) { 26 bitmap.config() != SkBitmap::kARGB_8888_Config) {
22 return false; 27 return false;
23 } 28 }
24 29
25 canvas_.drawBitmap(bitmap, bitmap_rect.x(), bitmap_rect.y()); 30 canvas_.drawBitmap(bitmap, bitmap_rect.x(), bitmap_rect.y());
26 return true; 31 return true;
27 } 32 }
28 33
34 // Return the given value, clipped to 0..max (inclusive)
35 static int RangeClip(int value, int max) {
36 return std::min(max, std::max(value, 0));
37 }
38
29 void BackingStore::ScrollRect(base::ProcessHandle process, 39 void BackingStore::ScrollRect(base::ProcessHandle process,
brettw 2009/02/04 20:36:06 Can you make some comment that this is a temporary
30 BitmapWireData bitmap, 40 BitmapWireData bitmap,
31 const gfx::Rect& bitmap_rect, 41 const gfx::Rect& bitmap_rect,
32 int dx, int dy, 42 int dx, int dy,
33 const gfx::Rect& clip_rect, 43 const gfx::Rect& clip_rect,
34 const gfx::Size& view_size) { 44 const gfx::Size& view_size) {
35 // TODO(port): implement scrolling 45 // On Windows, there's a ScrollDC call which performs horiz and vertical
36 NOTIMPLEMENTED(); 46 // scrolling
47 //
48 // clip_rect: MSDN says "The only bits that will be painted are the
49 // bits that remain inside this rectangle after the scroll operation has been
50 // completed."
51 //
52 // The Windows code always sets the whole backing store as the source of the
53 // scroll. Thus, we only have to worry about pixels which will end up inside
54 // the clipping rectangle. (Note that the clipping rectangle is not
55 // translated by the scrol.)
56
57 // We only support scrolling in one direction at a time.
58 DCHECK(dx == 0 || dy == 0);
59
60 if (bitmap.width() != bitmap_rect.width() ||
61 bitmap.height() != bitmap_rect.height() ||
62 bitmap.config() != SkBitmap::kARGB_8888_Config) {
63 return;
64 }
65
66 // We assume that |clip_rect| is within the backing store.
67
68 const SkBitmap &backing_bitmap = canvas_.getDevice()->accessBitmap(true);
69 const int stride = backing_bitmap.rowBytes();
70 uint8_t* x = static_cast<uint8_t*>(backing_bitmap.getPixels());
71
72 if (dx) {
73 // horizontal scroll. Positive values of |dx| scroll right.
74
75 // We know that |clip_rect| is the destination rectangle. The source
76 // rectangle, in an infinite world, would be the destination rectangle
77 // translated by -dx. However, we can't pull pixels from beyound the
78 // edge of the backing store. By truncating the source rectangle to the
79 // backing store, we might have made it thinner, thus we find the final
80 // dest rectangle by translating the resulting source rectangle back.
81 const int bs_width = canvas_.getDevice()->width();
82 const int src_rect_left = RangeClip(clip_rect.x() - dx, bs_width);
83 const int src_rect_right = RangeClip(clip_rect.right() - dx, bs_width);
84
85 const int dest_rect_left = RangeClip(src_rect_left + dx, bs_width);
86 const int dest_rect_right = RangeClip(src_rect_right + dx, bs_width);
87
88 DCHECK(dest_rect_right >= dest_rect_left);
89 DCHECK(src_rect_right >= src_rect_left);
90 DCHECK(dest_rect_right - dest_rect_left ==
91 src_rect_right - src_rect_left);
92
93 // This is the number of bytes to move per line at 4 bytes per pixel.
94 const int len = (dest_rect_right - dest_rect_left) * 4;
95
96 // Position the pixel data pointer at the top-left corner of the dest rect
97 x += clip_rect.y() * stride;
98 x += clip_rect.x() * 4;
99
100 // This is the number of bytes to reach left in order to find the source
101 // rectangle. (Will be negative for a left scroll.)
102 const int left_reach = dest_rect_left - src_rect_left;
103
104 for (int y = clip_rect.y(); y < clip_rect.bottom(); ++y) {
105 // Note that overlapping regions requires memmove, not memcpy.
106 memmove(x, x + left_reach, len);
107 x += stride;
108 }
109 } else {
110 // vertical scroll. Positive values of |dy| scroll down.
111
112 // The logic is very similar to the horizontal case, above.
113 const int bs_height = canvas_.getDevice()->height();
114 const int src_rect_top = RangeClip(clip_rect.y() - dy, bs_height);
115 const int src_rect_bottom = RangeClip(clip_rect.bottom() - dy, bs_height);
116
117 const int dest_rect_top = RangeClip(src_rect_top + dy, bs_height);
118 const int dest_rect_bottom = RangeClip(src_rect_bottom + dy, bs_height);
119
120 const int len = clip_rect.width() * 4;
121
122 DCHECK(dest_rect_bottom >= dest_rect_top);
123 DCHECK(src_rect_bottom >= src_rect_top);
124
125 // We need to consider the two directions separately here because the order
126 // of copying rows must vary to avoid writing data which we later need to
127 // read.
128 if (dy > 0) {
129 // scrolling down; dest rect is above src rect.
brettw 2009/02/04 20:36:06 This comment and the next 3 need capital letters a
130
131 // position the pixel data pointer at the top-left corner of the dest
132 // rect.
133 x += dest_rect_top * stride;
134 x += clip_rect.x() * 4;
135
136 DCHECK(dest_rect_top <= src_rect_top);
137 const int down_reach_bytes = stride * (src_rect_top - dest_rect_top);
138
139 for (int y = dest_rect_top; y < dest_rect_bottom; ++y) {
140 memcpy(x, x + down_reach_bytes, len);
141 x += stride;
142 }
143 } else {
144 // scrolling up; dest rect is below src rect.
145
146 // position the pixel data pointer at the bottom-left corner of the dest
147 // rect.
148 x += (dest_rect_bottom - 1) * stride;
149 x += clip_rect.x() * 4;
150
151 DCHECK(src_rect_top <= dest_rect_top);
152 const int up_reach_bytes = stride * (dest_rect_bottom - src_rect_bottom);
153
154 for (int y = dest_rect_bottom - 1; y >= dest_rect_top; --y) {
155 memcpy(x, x - up_reach_bytes, len);
156 x -= stride;
157 }
158 }
159 }
160
161 // Now paint the new bitmap data.
162 canvas_.drawBitmap(bitmap, bitmap_rect.x(), bitmap_rect.y());
163 return;
37 } 164 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698