summaryrefslogtreecommitdiffstats
path: root/content/browser/renderer_host
diff options
context:
space:
mode:
authorskaslev@chromium.org <skaslev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-09 02:51:14 +0000
committerskaslev@chromium.org <skaslev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-09 02:51:14 +0000
commitb4f00168368a7418d9e4109705b3b2f01a0c21eb (patch)
tree6c64161afd860e4d32e89defba34433e067568a6 /content/browser/renderer_host
parent478c6c3aa0165dfd120993c5ec0757d594e70fe6 (diff)
downloadchromium_src-b4f00168368a7418d9e4109705b3b2f01a0c21eb.zip
chromium_src-b4f00168368a7418d9e4109705b3b2f01a0c21eb.tar.gz
chromium_src-b4f00168368a7418d9e4109705b3b2f01a0c21eb.tar.bz2
Implemented browser side software compositing behind the --ui-enable-software-compositing flag.
BUG=124671, 161008 Review URL: https://chromiumcodereview.appspot.com/12542006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@187123 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/renderer_host')
-rw-r--r--content/browser/renderer_host/backing_store_win.cc51
-rw-r--r--content/browser/renderer_host/image_transport_factory.cc35
-rw-r--r--content/browser/renderer_host/software_output_device_linux.cc85
-rw-r--r--content/browser/renderer_host/software_output_device_linux.h38
-rw-r--r--content/browser/renderer_host/software_output_device_win.cc61
-rw-r--r--content/browser/renderer_host/software_output_device_win.h36
6 files changed, 266 insertions, 40 deletions
diff --git a/content/browser/renderer_host/backing_store_win.cc b/content/browser/renderer_host/backing_store_win.cc
index 77c0341..5ccafbb 100644
--- a/content/browser/renderer_host/backing_store_win.cc
+++ b/content/browser/renderer_host/backing_store_win.cc
@@ -48,29 +48,6 @@ HANDLE CreateDIB(HDC dc, int width, int height, int color_depth) {
return dib;
}
-void CallStretchDIBits(HDC hdc, int dest_x, int dest_y, int dest_w, int dest_h,
- int src_x, int src_y, int src_w, int src_h, void* pixels,
- const BITMAPINFO* bitmap_info) {
- // When blitting a rectangle that touches the bottom, left corner of the
- // bitmap, StretchDIBits looks at it top-down! For more details, see
- // http://wiki.allegro.cc/index.php?title=StretchDIBits.
- int rv;
- int bitmap_h = -bitmap_info->bmiHeader.biHeight;
- int bottom_up_src_y = bitmap_h - src_y - src_h;
- if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) {
- rv = StretchDIBits(hdc,
- dest_x, dest_h + dest_y - 1, dest_w, -dest_h,
- src_x, bitmap_h - src_y + 1, src_w, -src_h,
- pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
- } else {
- rv = StretchDIBits(hdc,
- dest_x, dest_y, dest_w, dest_h,
- src_x, bottom_up_src_y, src_w, src_h,
- pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
- }
- DCHECK(rv != GDI_ERROR);
-}
-
} // namespace
BackingStoreWin::BackingStoreWin(RenderWidgetHost* widget,
@@ -149,9 +126,11 @@ void BackingStoreWin::PaintToBackingStore(
gfx::Rect pixel_bitmap_rect = gfx::ToEnclosingRect(
gfx::ScaleRect(bitmap_rect, scale_factor));
- BITMAPINFOHEADER hdr;
+ BITMAPINFO bitmap_info;
+ memset(&bitmap_info, 0, sizeof(bitmap_info));
gfx::CreateBitmapHeader(pixel_bitmap_rect.width(),
- pixel_bitmap_rect.height(), &hdr);
+ pixel_bitmap_rect.height(),
+ &bitmap_info.bmiHeader);
// Account for a bitmap_rect that exceeds the bounds of our view.
gfx::Rect view_rect(size());
@@ -160,17 +139,17 @@ void BackingStoreWin::PaintToBackingStore(
gfx::Rect pixel_copy_rect = gfx::ToEnclosingRect(
gfx::ScaleRect(paint_rect, scale_factor));
gfx::Rect target_rect = pixel_copy_rect;
- CallStretchDIBits(hdc_,
- target_rect.x(),
- target_rect.y(),
- target_rect.width(),
- target_rect.height(),
- pixel_copy_rect.x() - pixel_bitmap_rect.x(),
- pixel_copy_rect.y() - pixel_bitmap_rect.y(),
- pixel_copy_rect.width(),
- pixel_copy_rect.height(),
- dib->memory(),
- reinterpret_cast<BITMAPINFO*>(&hdr));
+ gfx::StretchDIBits(hdc_,
+ target_rect.x(),
+ target_rect.y(),
+ target_rect.width(),
+ target_rect.height(),
+ pixel_copy_rect.x() - pixel_bitmap_rect.x(),
+ pixel_copy_rect.y() - pixel_bitmap_rect.y(),
+ pixel_copy_rect.width(),
+ pixel_copy_rect.height(),
+ dib->memory(),
+ &bitmap_info);
}
}
diff --git a/content/browser/renderer_host/image_transport_factory.cc b/content/browser/renderer_host/image_transport_factory.cc
index e37ea28..5970a3c 100644
--- a/content/browser/renderer_host/image_transport_factory.cc
+++ b/content/browser/renderer_host/image_transport_factory.cc
@@ -33,12 +33,16 @@
#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_setup.h"
+#include "ui/compositor/compositor_switches.h"
#include "ui/compositor/test_web_graphics_context_3d.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
#if defined(OS_WIN)
+#include "content/browser/renderer_host/software_output_device_win.h"
#include "ui/surface/accelerated_surface_win.h"
+#elif defined(USE_X11)
+#include "content/browser/renderer_host/software_output_device_linux.h"
#endif
namespace content {
@@ -669,6 +673,26 @@ WebKit::WebGraphicsContext3D* CreateTestContext() {
return test_context;
}
+class SoftwareTransportFactory : public DefaultTransportFactory {
+ public:
+ cc::OutputSurface* CreateOutputSurface(ui::Compositor* compositor) {
+#if defined(OS_WIN)
+ scoped_ptr<SoftwareOutputDeviceWin> software_device(
+ new SoftwareOutputDeviceWin(compositor));
+ return new cc::OutputSurface(
+ software_device.PassAs<cc::SoftwareOutputDevice>());
+#elif defined(USE_X11)
+ scoped_ptr<SoftwareOutputDeviceLinux> software_device(
+ new SoftwareOutputDeviceLinux(compositor));
+ return new cc::OutputSurface(
+ software_device.PassAs<cc::SoftwareOutputDevice>());
+#else
+ NOTIMPLEMENTED();
+ return NULL;
+#endif
+ }
+};
+
} // anonymous namespace
// static
@@ -677,10 +701,13 @@ void ImageTransportFactory::Initialize() {
if (command_line->HasSwitch(switches::kTestCompositor)) {
ui::SetupTestCompositor();
}
- if (ui::IsTestCompositorEnabled())
- g_factory = new DefaultTransportFactory();
- else
- g_factory = new GpuProcessTransportFactory();
+ if (ui::IsTestCompositorEnabled()) {
+ g_factory = new DefaultTransportFactory;
+ } else if (command_line->HasSwitch(switches::kUIEnableSoftwareCompositing)) {
+ g_factory = new SoftwareTransportFactory;
+ } else {
+ g_factory = new GpuProcessTransportFactory;
+ }
ui::ContextFactory::SetInstance(g_factory->AsContextFactory());
}
diff --git a/content/browser/renderer_host/software_output_device_linux.cc b/content/browser/renderer_host/software_output_device_linux.cc
new file mode 100644
index 0000000..58289dd
--- /dev/null
+++ b/content/browser/renderer_host/software_output_device_linux.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/software_output_device_linux.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "content/public/browser/browser_thread.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkDevice.h"
+#include "ui/compositor/compositor.h"
+
+namespace content {
+
+SoftwareOutputDeviceLinux::SoftwareOutputDeviceLinux(ui::Compositor* compositor)
+ : compositor_(compositor),
+ display_(ui::GetXDisplay()),
+ gc_(NULL),
+ image_(NULL) {
+ // TODO(skaslev) Remove this when crbug.com/180702 is fixed.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ gc_ = XCreateGC(display_, compositor_->widget(), 0, NULL);
+}
+
+SoftwareOutputDeviceLinux::~SoftwareOutputDeviceLinux() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ XFreeGC(display_, gc_);
+ ClearImage();
+}
+
+void SoftwareOutputDeviceLinux::ClearImage() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (image_) {
+ // XDestroyImage deletes the data referenced by the image which
+ // is actually owned by the device_. So we have to reset data here.
+ image_->data = NULL;
+ XDestroyImage(image_);
+ image_ = NULL;
+ }
+}
+
+void SoftwareOutputDeviceLinux::Resize(const gfx::Size& viewport_size) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ cc::SoftwareOutputDevice::Resize(viewport_size);
+
+ ClearImage();
+ if (!device_)
+ return;
+
+ const SkBitmap& bitmap = device_->accessBitmap(false);
+ image_ = XCreateImage(display_, CopyFromParent,
+ DefaultDepth(display_, DefaultScreen(display_)),
+ ZPixmap, 0,
+ static_cast<char*>(bitmap.getPixels()),
+ viewport_size_.width(), viewport_size_.height(),
+ 32, 4 * viewport_size_.width());
+}
+
+void SoftwareOutputDeviceLinux::EndPaint(cc::SoftwareFrameData* frame_data) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(device_);
+ DCHECK(frame_data == NULL);
+
+ if (!device_)
+ return;
+
+ gfx::Rect rect = damage_rect_;
+ rect.Intersect(gfx::Rect(viewport_size_));
+ if (rect.IsEmpty())
+ return;
+
+ // TODO(skaslev): Maybe switch XShmPutImage since it's async.
+ XPutImage(display_, compositor_->widget(), gc_, image_,
+ rect.x(), rect.y(),
+ rect.x(), rect.y(),
+ rect.width(), rect.height());
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/software_output_device_linux.h b/content/browser/renderer_host/software_output_device_linux.h
new file mode 100644
index 0000000..654936e
--- /dev/null
+++ b/content/browser/renderer_host/software_output_device_linux.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_LINUX_H_
+#define CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_LINUX_H_
+
+#include "cc/software_output_device.h"
+#include "ui/base/x/x11_util.h"
+
+namespace ui {
+class Compositor;
+}
+
+namespace content {
+
+class SoftwareOutputDeviceLinux : public cc::SoftwareOutputDevice {
+ public:
+ explicit SoftwareOutputDeviceLinux(ui::Compositor* compositor);
+
+ virtual ~SoftwareOutputDeviceLinux();
+
+ virtual void Resize(const gfx::Size& viewport_size) OVERRIDE;
+
+ virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE;
+
+ private:
+ void ClearImage();
+
+ ui::Compositor* compositor_;
+ Display* display_;
+ GC gc_;
+ XImage* image_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_LINUX_H_
diff --git a/content/browser/renderer_host/software_output_device_win.cc b/content/browser/renderer_host/software_output_device_win.cc
new file mode 100644
index 0000000..b78cd4da
--- /dev/null
+++ b/content/browser/renderer_host/software_output_device_win.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/software_output_device_win.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkDevice.h"
+#include "ui/compositor/compositor.h"
+#include "ui/gfx/gdi_util.h"
+
+namespace content {
+
+SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(ui::Compositor* compositor)
+ : compositor_(compositor) {
+ // TODO(skaslev) Remove this when crbug.com/180702 is fixed.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ hdc_ = ::GetWindowDC(compositor->widget());
+}
+
+SoftwareOutputDeviceWin::~SoftwareOutputDeviceWin() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ ::ReleaseDC(compositor_->widget(), hdc_);
+}
+
+void SoftwareOutputDeviceWin::Resize(const gfx::Size& viewport_size) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ cc::SoftwareOutputDevice::Resize(viewport_size);
+ memset(&bitmap_info_, 0, sizeof(bitmap_info_));
+ gfx::CreateBitmapHeader(viewport_size_.width(), viewport_size_.height(),
+ &bitmap_info_.bmiHeader);
+}
+
+void SoftwareOutputDeviceWin::EndPaint(cc::SoftwareFrameData* frame_data) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(device_);
+ DCHECK(frame_data == NULL);
+
+ if (!device_)
+ return;
+
+ gfx::Rect rect = damage_rect_;
+ rect.Intersect(gfx::Rect(viewport_size_));
+ if (rect.IsEmpty())
+ return;
+
+ const SkBitmap& bitmap = device_->accessBitmap(false);
+ gfx::StretchDIBits(hdc_,
+ rect.x(), rect.y(),
+ rect.width(), rect.height(),
+ rect.x(), rect.y(),
+ rect.width(), rect.height(),
+ bitmap.getPixels(),
+ &bitmap_info_);
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/software_output_device_win.h b/content/browser/renderer_host/software_output_device_win.h
new file mode 100644
index 0000000..ab8f6bf
--- /dev/null
+++ b/content/browser/renderer_host/software_output_device_win.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_WIN_H_
+#define CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_WIN_H_
+
+#include "cc/software_output_device.h"
+
+#include <windows.h>
+
+namespace ui {
+class Compositor;
+}
+
+namespace content {
+
+class SoftwareOutputDeviceWin : public cc::SoftwareOutputDevice {
+ public:
+ explicit SoftwareOutputDeviceWin(ui::Compositor* compositor);
+
+ virtual ~SoftwareOutputDeviceWin();
+
+ virtual void Resize(const gfx::Size& viewport_size) OVERRIDE;
+
+ virtual void EndPaint(cc::SoftwareFrameData* frame_data) OVERRIDE;
+
+ private:
+ ui::Compositor* compositor_;
+ HDC hdc_;
+ BITMAPINFO bitmap_info_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_SOFTWARE_OUTPUT_DEVICE_WIN_H_