Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1063)

Side by Side Diff: ui/gfx/surface/transport_dib_linux.cc

Issue 10351002: ui: Move surface/ directory out of gfx/, up to ui/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix gpu DEPS Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gfx/surface/transport_dib_android.cc ('k') | ui/gfx/surface/transport_dib_mac.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/surface/transport_dib.h"
6
7 #include <errno.h>
8 #include <stdlib.h>
9 #include <sys/ipc.h>
10 #include <sys/shm.h>
11
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "skia/ext/platform_canvas.h"
15 #include "ui/base/x/x11_util.h"
16 #include "ui/gfx/size.h"
17
18 // The shmat system call uses this as it's invalid return address
19 static void *const kInvalidAddress = (void*) -1;
20
21 TransportDIB::TransportDIB()
22 : address_(kInvalidAddress),
23 x_shm_(0),
24 display_(NULL),
25 size_(0) {
26 }
27
28 TransportDIB::~TransportDIB() {
29 if (address_ != kInvalidAddress) {
30 shmdt(address_);
31 address_ = kInvalidAddress;
32 }
33
34 if (x_shm_) {
35 DCHECK(display_);
36 ui::DetachSharedMemory(display_, x_shm_);
37 }
38 }
39
40 // static
41 TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) {
42 // We use a mode of 0666 since the X server won't attach to memory which is
43 // 0600 since it can't know if it (as a root process) is being asked to map
44 // someone else's private shared memory region.
45 const int shmkey = shmget(IPC_PRIVATE, size, 0666);
46 if (shmkey == -1) {
47 DLOG(ERROR) << "Failed to create SysV shared memory region"
48 << " errno:" << errno;
49 return NULL;
50 }
51
52 void* address = shmat(shmkey, NULL /* desired address */, 0 /* flags */);
53 // Here we mark the shared memory for deletion. Since we attached it in the
54 // line above, it doesn't actually get deleted but, if we crash, this means
55 // that the kernel will automatically clean it up for us.
56 shmctl(shmkey, IPC_RMID, 0);
57 if (address == kInvalidAddress)
58 return NULL;
59
60 TransportDIB* dib = new TransportDIB;
61
62 dib->key_.shmkey = shmkey;
63 dib->address_ = address;
64 dib->size_ = size;
65 return dib;
66 }
67
68 // static
69 TransportDIB* TransportDIB::Map(Handle handle) {
70 scoped_ptr<TransportDIB> dib(CreateWithHandle(handle));
71 if (!dib->Map())
72 return NULL;
73 return dib.release();
74 }
75
76 // static
77 TransportDIB* TransportDIB::CreateWithHandle(Handle shmkey) {
78 TransportDIB* dib = new TransportDIB;
79 dib->key_.shmkey = shmkey;
80 return dib;
81 }
82
83 // static
84 bool TransportDIB::is_valid_handle(Handle dib) {
85 return dib >= 0;
86 }
87
88 // static
89 bool TransportDIB::is_valid_id(Id id) {
90 return id.shmkey != -1;
91 }
92
93 skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) {
94 if (address_ == kInvalidAddress && !Map())
95 return NULL;
96 scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas);
97 if (!canvas->initialize(w, h, true, reinterpret_cast<uint8_t*>(memory())))
98 return NULL;
99 return canvas.release();
100 }
101
102 bool TransportDIB::Map() {
103 if (!is_valid_id(key_))
104 return false;
105 if (address_ != kInvalidAddress)
106 return true;
107
108 struct shmid_ds shmst;
109 if (shmctl(key_.shmkey, IPC_STAT, &shmst) == -1)
110 return false;
111
112 void* address = shmat(key_.shmkey, NULL /* desired address */, 0 /* flags */);
113 if (address == kInvalidAddress)
114 return false;
115
116 address_ = address;
117 size_ = shmst.shm_segsz;
118 return true;
119 }
120
121 void* TransportDIB::memory() const {
122 DCHECK_NE(address_, kInvalidAddress);
123 return address_;
124 }
125
126 TransportDIB::Id TransportDIB::id() const {
127 return key_;
128 }
129
130 TransportDIB::Handle TransportDIB::handle() const {
131 return key_.shmkey;
132 }
133
134 XID TransportDIB::MapToX(Display* display) {
135 if (!x_shm_) {
136 x_shm_ = ui::AttachSharedMemory(display, key_.shmkey);
137 display_ = display;
138 }
139
140 return x_shm_;
141 }
OLDNEW
« no previous file with comments | « ui/gfx/surface/transport_dib_android.cc ('k') | ui/gfx/surface/transport_dib_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698