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

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

Issue 13582008: Simplify the transport dib situation across our various platforms, as a (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 8 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
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/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 inflight_counter_(0),
26 detached_(false),
27 size_(0) {
28 }
29
30 TransportDIB::~TransportDIB() {
31 if (address_ != kInvalidAddress) {
32 shmdt(address_);
33 address_ = kInvalidAddress;
34 }
35
36 if (x_shm_) {
37 DCHECK(display_);
38 ui::DetachSharedMemory(display_, x_shm_);
39 }
40 }
41
42 // static
43 TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) {
44 const int shmkey = shmget(IPC_PRIVATE, size, 0600);
45 if (shmkey == -1) {
46 DLOG(ERROR) << "Failed to create SysV shared memory region"
47 << " errno:" << errno;
48 return NULL;
49 } else {
50 VLOG(1) << "Created SysV shared memory region " << shmkey;
51 }
52
53 void* address = shmat(shmkey, NULL /* desired address */, 0 /* flags */);
54 // Here we mark the shared memory for deletion. Since we attached it in the
55 // line above, it doesn't actually get deleted but, if we crash, this means
56 // that the kernel will automatically clean it up for us.
57 shmctl(shmkey, IPC_RMID, 0);
58 if (address == kInvalidAddress)
59 return NULL;
60
61 TransportDIB* dib = new TransportDIB;
62
63 dib->key_.shmkey = shmkey;
64 dib->address_ = address;
65 dib->size_ = size;
66 return dib;
67 }
68
69 // static
70 TransportDIB* TransportDIB::Map(Handle handle) {
71 scoped_ptr<TransportDIB> dib(CreateWithHandle(handle));
72 if (!dib->Map())
73 return NULL;
74 return dib.release();
75 }
76
77 // static
78 TransportDIB* TransportDIB::CreateWithHandle(Handle shmkey) {
79 TransportDIB* dib = new TransportDIB;
80 dib->key_.shmkey = shmkey;
81 return dib;
82 }
83
84 // static
85 bool TransportDIB::is_valid_handle(Handle dib) {
86 return dib >= 0;
87 }
88
89 // static
90 bool TransportDIB::is_valid_id(Id id) {
91 return id.shmkey != -1;
92 }
93
94 skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) {
95 if ((address_ == kInvalidAddress && !Map()) || !VerifyCanvasSize(w, h))
96 return NULL;
97 return skia::CreatePlatformCanvas(w, h, true,
98 reinterpret_cast<uint8_t*>(memory()),
99 skia::RETURN_NULL_ON_FAILURE);
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 }
142
143 void TransportDIB::DecreaseInFlightCounter() {
144 CHECK(inflight_counter_);
145 inflight_counter_--;
146 if (!inflight_counter_ && detached_)
147 delete this;
148 }
149
150 void TransportDIB::Detach() {
151 CHECK(!detached_);
152 detached_ = true;
153 if (!inflight_counter_)
154 delete this;
155 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698