diff --git a/libcef/webwidget_host_win.cc b/libcef/webwidget_host_win.cc index 87b878da4..9a91acdc6 100644 --- a/libcef/webwidget_host_win.cc +++ b/libcef/webwidget_host_win.cc @@ -287,10 +287,11 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { DCHECK(dx || dy); // Invalidate and re-paint the entire scroll rect if: - // 1. We're in a state where we cannot draw into the view right now, or - // 2. The rect is being scrolled by more than the size of the view, or - // 3. The scroll rect intersects the current paint region. - if (!canvas_.get() || layouting_ || painting_ || + // 1. Window rendering is disabled, or + // 2. We're in a state where we cannot draw into the view right now, or + // 3. The rect is being scrolled by more than the size of the view, or + // 4. The scroll rect intersects the current paint region. + if (!view_ || !canvas_.get() || layouting_ || painting_ || abs(dx) >= clip_rect.width() || abs(dy) >= clip_rect.height() || paint_rgn_.intersects(convertToSkiaRect(clip_rect))) { DidInvalidateRect(clip_rect); diff --git a/tests/cefclient/osrplugin.cpp b/tests/cefclient/osrplugin.cpp index 00007d899..6444d5630 100644 --- a/tests/cefclient/osrplugin.cpp +++ b/tests/cefclient/osrplugin.cpp @@ -287,11 +287,21 @@ class ClientOSRHandler : public CefClient, glBindTexture(GL_TEXTURE_2D, g_textureID); if (type == PET_VIEW) { + SetBufferSize(g_width, g_height, true); // Paint the view. - if (g_offscreenTransparent) - SetRGBA(buffer, g_width, g_height, true); - else - SetRGB(buffer, g_width, g_height, true); + if (g_offscreenTransparent) { + RectList::const_iterator i = dirtyRects.begin(); + for (; i != dirtyRects.end(); ++i) { + ConvertToRGBARect(*i, (unsigned char*)buffer, view_buffer_, g_width, + g_height); + } + } else { + RectList::const_iterator i = dirtyRects.begin(); + for (i; i != dirtyRects.end(); ++i) { + ConvertToRGBRect(*i, (unsigned char*)buffer, view_buffer_, g_width, + g_height); + } + } // Update the whole texture. This is done for simplicity instead of // updating just the dirty region. @@ -391,6 +401,24 @@ class ClientOSRHandler : public CefClient, } } + static void ConvertToRGBARect(const CefRect& clipRect, + const unsigned char* src, unsigned char* dst, + int width, int height) { + int sp = 0, dp = (height-1) * width * 4; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++, dp += 4, sp += 4) { + if ((clipRect.x <= j) && (clipRect.x + clipRect.width > j) && + (clipRect.y <= i) && (clipRect.y + clipRect.height > i)) { + dst[dp] = src[sp+2]; // R + dst[dp+1] = src[sp+1]; // G + dst[dp+2] = src[sp]; // B + dst[dp+3] = src[sp+3]; // A + } + } + dp -= width * 8; + } + } + // Set the contents of the RGB buffer. void SetRGB(const void* src, int width, int height, bool view) { SetBufferSize(width, height, view); @@ -412,6 +440,23 @@ class ClientOSRHandler : public CefClient, } } + static void ConvertToRGBRect(const CefRect& clipRect, + const unsigned char* src, unsigned char* dst, + int width, int height) { + int sp = 0, dp = (height-1) * width * 3; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++, dp += 3, sp += 4) { + if ((clipRect.x <= j) && (clipRect.x + clipRect.width > j) && + (clipRect.y <= i) && (clipRect.y + clipRect.height > i)) { + dst[dp] = src[sp+2]; // R + dst[dp+1] = src[sp+1]; // G + dst[dp+2] = src[sp]; // B + } + } + dp -= width * 6; + } + } + ClientPlugin* plugin_; unsigned char* view_buffer_; int view_buffer_size_;