summaryrefslogtreecommitdiffstats
path: root/chrome/gpu/gpu_backing_store_glx.cc
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-28 16:18:57 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-28 16:18:57 +0000
commit8386a521873c4ea37b2682fff32260acdf245138 (patch)
treea0fd60732a77e1ed1e0d3516e5cb82114188fdd5 /chrome/gpu/gpu_backing_store_glx.cc
parentd8921c432923fd6bdbbc176110258c2e3416eaa7 (diff)
downloadchromium_src-8386a521873c4ea37b2682fff32260acdf245138.zip
chromium_src-8386a521873c4ea37b2682fff32260acdf245138.tar.gz
chromium_src-8386a521873c4ea37b2682fff32260acdf245138.tar.bz2
Add scrolling to the GPU-accelerated backing store. This also fixes some bugs
in the regular painting mode and adds handling for expose events. Accelerated tabs now seem to look and behave properly as far as I can tell. Scrolling works by keeping a secondary texture which the current backing store is painted into. To save copies and excess texture creation, the current texture and the newly generated one are just swapped whan scrolling completes. Scrolling does not actually trigger painting to the screen. This is because scrolling is always followed by a paint to the exposed area, which then triggers copying the GPU backing store to the screen. BUG=none TEST=none Review URL: http://codereview.chromium.org/552207 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37409 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/gpu/gpu_backing_store_glx.cc')
-rw-r--r--chrome/gpu/gpu_backing_store_glx.cc78
1 files changed, 67 insertions, 11 deletions
diff --git a/chrome/gpu/gpu_backing_store_glx.cc b/chrome/gpu/gpu_backing_store_glx.cc
index e653284..015e913 100644
--- a/chrome/gpu/gpu_backing_store_glx.cc
+++ b/chrome/gpu/gpu_backing_store_glx.cc
@@ -32,9 +32,8 @@ GpuBackingStoreGLX::GpuBackingStoreGLX(GpuViewX* view,
glBindTexture(GL_TEXTURE_2D, texture_id_);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- DCHECK(glGetError() == GL_NO_ERROR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
GpuBackingStoreGLX::~GpuBackingStoreGLX() {
@@ -83,7 +82,70 @@ void GpuBackingStoreGLX::OnPaintToBackingStore(
void GpuBackingStoreGLX::OnScrollBackingStore(int dx, int dy,
const gfx::Rect& clip_rect,
const gfx::Size& view_size) {
+ // Create a framebuffer to render our scrolled texture into.
+ GpuBackingStoreGLXContext* context = view_->gpu_thread()->GetGLXContext();
+ if (!context->BindTextureForScrolling(view_->window(), size_))
+ return;
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, texture_id_);
+
+ // Set up the the tranform so we can paint exact pixels to the screen, with
+ // (0, 0) at the bottom left.
+ float w = static_cast<float>(size_.width());
+ float h = static_cast<float>(size_.height());
+ glViewport(0, 0, size_.width(), size_.height());
+ glLoadIdentity();
+ glOrtho(0.0, w, 0.0, h, -1.0, 1.0);
+
+ // Paint the non-scrolled background of the page. Note that we try to avoid
+ // this if the entire thing is scrolling, which is a common case.
+ if (view_size != clip_rect.size()) {
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(0.0, 0.0);
+
+ glTexCoord2f(0.0f, 1.0f);
+ glVertex2f(0.0, h);
+
+ glTexCoord2f(1.0f, 1.0f);
+ glVertex2f(w, h);
+
+ glTexCoord2f(1.0f, 0.0f);
+ glVertex2f(w, 0.0);
+ glEnd();
+ }
+
+ // Constrain the painting to only the area we're scrolling. Compute the clip
+ // rect in OpenGL pixel coords, which uses the lower-left as the origin.
+ gfx::Rect gl_clip_rect(clip_rect.x(), clip_rect.y(),
+ clip_rect.width(), clip_rect.height());
+
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(gl_clip_rect.x(), gl_clip_rect.y(),
+ gl_clip_rect.width(), gl_clip_rect.height());
+
+ // Paint the offset texture.
+ glTranslatef(static_cast<float>(dx), static_cast<float>(dy), 0.0f);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(0.0, 0.0);
+
+ glTexCoord2f(0.0f, 1.0f);
+ glVertex2f(0.0, h);
+
+ glTexCoord2f(1.0f, 1.0f);
+ glVertex2f(w, h);
+
+ glTexCoord2f(1.0f, 0.0f);
+ glVertex2f(w, 0.0);
+ glEnd();
+ glDisable(GL_SCISSOR_TEST);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ texture_id_ = context->SwapTextureForScrolling(texture_id_, size_);
+ glFlush();
+ DCHECK(texture_id_);
}
void GpuBackingStoreGLX::PaintOneRectToBackingStore(
@@ -113,14 +175,10 @@ void GpuBackingStoreGLX::PaintOneRectToBackingStore(
// the updated bitmap to avoid the copy. We will have to benchmark that
// approach against making the copy here to see if it performs better on
// the systems we're targeting.
- SkIRect subset;
- subset.fLeft = copy_rect.x() - bitmap_rect.x();
- subset.fTop = copy_rect.y() - bitmap_rect.y();
- subset.fRight = subset.fLeft + copy_rect.width();
- subset.fBottom = subset.fTop + copy_rect.height();
SkIRect sk_copy_rect = { copy_rect.x() - bitmap_rect.x(),
copy_rect.y() - bitmap_rect.y(),
- copy_rect.right(), copy_rect.bottom() };
+ copy_rect.right() - bitmap_rect.x(),
+ copy_rect.bottom() - bitmap_rect.y()};
// extractSubset will not acutually make a copy, and Skia will refer to the
// original data which is not what we want, since rows won't be contiguous.
@@ -139,7 +197,6 @@ void GpuBackingStoreGLX::PaintOneRectToBackingStore(
copy_rect.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE,
copy_bitmap.getAddr32(0, 0));
texture_size_ = copy_rect.size();
- DCHECK(glGetError() == GL_NO_ERROR);
} else {
/* Debugging code for why the below call may fail.
int existing_width = 0, existing_height = 0;
@@ -152,7 +209,6 @@ void GpuBackingStoreGLX::PaintOneRectToBackingStore(
copy_rect.width(), copy_rect.height(),
GL_BGRA, GL_UNSIGNED_BYTE,
copy_bitmap.getAddr32(0, 0));
- DCHECK(glGetError() == GL_NO_ERROR);
/* Enable if you're having problems with TexSubImage failing.
int err = glGetError();
DCHECK(err == GL_NO_ERROR) << "Error " << err <<