OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ui/gfx/ozone/impl/dri_surface.h" | |
6 | |
7 #include <errno.h> | |
8 #include <sys/mman.h> | |
9 #include <sys/types.h> | |
10 #include <xf86drm.h> | |
11 | |
12 #include "base/logging.h" | |
13 #include "third_party/skia/include/core/SkBitmap.h" | |
14 #include "third_party/skia/include/core/SkBitmapDevice.h" | |
15 #include "third_party/skia/include/core/SkCanvas.h" | |
16 #include "ui/gfx/ozone/impl/dri_skbitmap.h" | |
17 #include "ui/gfx/ozone/impl/hardware_display_controller.h" | |
18 #include "ui/gfx/skia_util.h" | |
19 | |
20 namespace gfx { | |
21 | |
22 namespace { | |
23 | |
24 // Extends the SkBitmapDevice to allow setting the SkPixelRef. We use the setter | |
25 // to change the SkPixelRef such that the device always points to the | |
26 // backbuffer. | |
27 class CustomSkBitmapDevice : public SkBitmapDevice { | |
28 public: | |
29 CustomSkBitmapDevice(const SkBitmap& bitmap) : SkBitmapDevice(bitmap) {} | |
30 virtual ~CustomSkBitmapDevice() {} | |
31 | |
32 void SetPixelRef(SkPixelRef* pixel_ref) { setPixelRef(pixel_ref, 0); } | |
33 | |
34 private: | |
35 DISALLOW_COPY_AND_ASSIGN(CustomSkBitmapDevice); | |
36 }; | |
37 | |
38 } // namespace | |
39 | |
40 //////////////////////////////////////////////////////////////////////////////// | |
41 // DriSurface implementation | |
42 | |
43 DriSurface::DriSurface( | |
44 HardwareDisplayController* controller) | |
45 : controller_(controller), | |
46 bitmaps_(), | |
47 front_buffer_(0) { | |
48 } | |
49 | |
50 DriSurface::~DriSurface() { | |
51 } | |
52 | |
53 bool DriSurface::Initialize() { | |
54 for (int i = 0; i < 2; ++i) { | |
55 bitmaps_[i].reset(CreateBuffer()); | |
56 // TODO(dnicoara) Should select the configuration based on what the | |
57 // underlying system supports. | |
58 bitmaps_[i]->setConfig(SkBitmap::kARGB_8888_Config, | |
59 controller_->get_mode().hdisplay, | |
60 controller_->get_mode().vdisplay); | |
61 | |
62 if (!bitmaps_[i]->Initialize()) { | |
63 return false; | |
64 } | |
65 } | |
66 | |
67 skia_device_ = skia::AdoptRef( | |
68 new CustomSkBitmapDevice(*bitmaps_[front_buffer_ ^ 1].get())); | |
69 skia_canvas_ = skia::AdoptRef(new SkCanvas(skia_device_.get())); | |
70 | |
71 return true; | |
72 } | |
73 | |
74 uint32_t DriSurface::GetFramebufferId() const { | |
75 CHECK(bitmaps_[0].get() && bitmaps_[1].get()); | |
76 return bitmaps_[front_buffer_ ^ 1]->get_framebuffer(); | |
77 } | |
78 | |
79 // This call is made after the hardware just started displaying our back buffer. | |
80 // We need to update our pointer reference and synchronize the two buffers. | |
81 void DriSurface::SwapBuffers() { | |
82 CHECK(bitmaps_[0].get() && bitmaps_[1].get()); | |
83 | |
84 // Update our front buffer pointer. | |
85 front_buffer_ ^= 1; | |
86 | |
87 // Unlocking will unset the pixel pointer, so it won't be pointing to the old | |
88 // PixelRef. | |
89 skia_device_->accessBitmap(false).unlockPixels(); | |
90 // Update the backing pixels for the bitmap device. | |
91 static_cast<CustomSkBitmapDevice*>(skia_device_.get())->SetPixelRef( | |
92 bitmaps_[front_buffer_ ^ 1]->pixelRef()); | |
93 // Locking the pixels will set the pixel pointer based on the PixelRef value. | |
94 skia_device_->accessBitmap(false).lockPixels(); | |
95 | |
96 SkIRect device_damage; | |
97 skia_canvas_->getClipDeviceBounds(&device_damage); | |
98 SkRect damage = SkRect::Make(device_damage); | |
99 | |
100 skia_canvas_->drawBitmapRectToRect(*bitmaps_[front_buffer_].get(), | |
101 &damage, | |
102 damage); | |
103 } | |
104 | |
105 SkCanvas* DriSurface::GetDrawableForWidget() { | |
106 return skia_canvas_.get(); | |
107 } | |
108 | |
109 DriSkBitmap* DriSurface::CreateBuffer() { | |
110 return new DriSkBitmap(controller_->get_fd()); | |
111 } | |
112 | |
113 } // namespace gfx | |
OLD | NEW |