Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / ozone / platform / dri / dri_surface.cc
index d6b4f59..d0d4f56 100644 (file)
@@ -4,77 +4,99 @@
 
 #include "ui/ozone/platform/dri/dri_surface.h"
 
-#include <errno.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <xf86drm.h>
-
 #include "base/logging.h"
+#include "base/message_loop/message_loop.h"
 #include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkSurface.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/ozone/platform/dri/dri_buffer.h"
+#include "ui/ozone/platform/dri/dri_vsync_provider.h"
 #include "ui/ozone/platform/dri/dri_wrapper.h"
+#include "ui/ozone/platform/dri/hardware_display_controller.h"
 
 namespace ui {
 
+namespace {
+
+scoped_refptr<DriBuffer> AllocateBuffer(DriWrapper* dri,
+                                        const gfx::Size& size) {
+  scoped_refptr<DriBuffer> buffer(new DriBuffer(dri));
+  SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
+
+  bool initialized = buffer->Initialize(info);
+  DCHECK(initialized) << "Failed to create drm buffer.";
+
+  return buffer;
+}
+
+}  // namespace
+
 DriSurface::DriSurface(
-    DriWrapper* dri, const gfx::Size& size)
+    DriWrapper* dri,
+    const base::WeakPtr<HardwareDisplayController>& controller)
     : dri_(dri),
-      bitmaps_(),
+      buffers_(),
       front_buffer_(0),
-      size_(size) {
+      controller_(controller) {
 }
 
 DriSurface::~DriSurface() {
 }
 
-bool DriSurface::Initialize() {
-  for (size_t i = 0; i < arraysize(bitmaps_); ++i) {
-    bitmaps_[i].reset(CreateBuffer());
-    // TODO(dnicoara) Should select the configuration based on what the
-    // underlying system supports.
-    SkImageInfo info = SkImageInfo::Make(size_.width(),
-                                         size_.height(),
-                                         kPMColor_SkColorType,
-                                         kPremul_SkAlphaType);
-    if (!bitmaps_[i]->Initialize(info)) {
-      return false;
-    }
-  }
-
-  return true;
+skia::RefPtr<SkCanvas> DriSurface::GetCanvas() {
+  return skia::SharePtr(surface_->getCanvas());
 }
 
-uint32_t DriSurface::GetFramebufferId() const {
-  CHECK(backbuffer());
-  return backbuffer()->framebuffer();
-}
+void DriSurface::ResizeCanvas(const gfx::Size& viewport_size) {
+  SkImageInfo info = SkImageInfo::MakeN32(
+      viewport_size.width(), viewport_size.height(), kOpaque_SkAlphaType);
+  surface_ = skia::AdoptRef(SkSurface::NewRaster(info));
 
-uint32_t DriSurface::GetHandle() const {
-  CHECK(backbuffer());
-  return backbuffer()->handle();
+  if (!controller_)
+    return;
+
+  // For the display buffers use the mode size since a |viewport_size| smaller
+  // than the display size will not scanout.
+  gfx::Size mode_size(controller_->get_mode().hdisplay,
+                      controller_->get_mode().vdisplay);
+  for (size_t i = 0; i < arraysize(buffers_); ++i)
+    buffers_[i] = AllocateBuffer(dri_, mode_size);
 }
 
-// This call is made after the hardware just started displaying our back buffer.
-// We need to update our pointer reference and synchronize the two buffers.
-void DriSurface::SwapBuffers() {
-  CHECK(frontbuffer());
-  CHECK(backbuffer());
+void DriSurface::PresentCanvas(const gfx::Rect& damage) {
+  DCHECK(base::MessageLoopForUI::IsCurrent());
+  DCHECK(buffers_[front_buffer_ ^ 1]);
+
+  if (!controller_)
+    return;
+
+  controller_->QueueOverlayPlane(OverlayPlane(buffers_[front_buffer_ ^ 1]));
+
+  UpdateNativeSurface(damage);
+  controller_->SchedulePageFlip();
+  controller_->WaitForPageFlipEvent();
 
   // Update our front buffer pointer.
   front_buffer_ ^= 1;
 }
 
-gfx::Size DriSurface::Size() const {
-  return size_;
+scoped_ptr<gfx::VSyncProvider> DriSurface::CreateVSyncProvider() {
+  return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(controller_));
 }
 
-SkCanvas* DriSurface::GetDrawableForWidget() {
-  CHECK(backbuffer());
-  return backbuffer()->canvas();
-}
+void DriSurface::UpdateNativeSurface(const gfx::Rect& damage) {
+  SkCanvas* canvas = buffers_[front_buffer_ ^ 1]->GetCanvas();
+
+  // The DriSurface is double buffered, so the current back buffer is
+  // missing the previous update. Expand damage region.
+  SkRect real_damage = RectToSkRect(UnionRects(damage, last_damage_));
 
-DriBuffer* DriSurface::CreateBuffer() { return new DriBuffer(dri_); }
+  // Copy damage region.
+  skia::RefPtr<SkImage> image = skia::AdoptRef(surface_->newImageSnapshot());
+  image->draw(canvas, &real_damage, real_damage, NULL);
+
+  last_damage_ = damage;
+}
 
 }  // namespace ui