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

Side by Side Diff: chromecast/ui/gfx/surface_directfb.cc

Issue 223143003: Initial checkin of chromecast content embedder (cast_shell) and related build scripts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add an additional function in gl_surface_cast.cc Created 6 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
OLDNEW
(Empty)
1 // Copyright (c) 2014 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 "chromecast/ui/gfx/surface_directfb.h"
6
7 #include "base/logging.h"
8 #include "chromecast/ui/gfx/gfx_plane_directfb.h"
9 #include "ui/gfx/point.h"
10 #include "ui/gfx/rect.h"
11 #include "ui/gfx/size.h"
12
13 namespace gfx {
14 namespace chromecast {
15
16 SurfaceDirectFb::SurfaceDirectFb(GfxPlaneDirectFb* arg_plane,
17 const Size& arg_size, bool arg_primary)
18 : Surface(arg_plane, arg_size),
19 primary_(arg_primary) {
20 DFBSurfaceDescription dsc;
21
22 if (primary_) {
23 // fix directfb's abuse of an enum as a bitfield, allowed in C, not C++
24 dsc.flags = static_cast<DFBSurfaceDescriptionFlags>(DSDESC_CAPS |
25 DSDESC_PIXELFORMAT);
26 #if defined(DOUBLE_BUFFER)
27 dsc.caps = static_cast<DFBSurfaceCapabilities>(DSCAPS_PRIMARY |
28 DSCAPS_DOUBLE);
29 #else
30 dsc.caps = DSCAPS_PRIMARY;
31 // Add DSCAPS_DOUBLE to double-buffer, and if so, we'll need to disable
32 // autoflip-window, and explictly call Flip.
33 //
34 #endif
35 } else {
36 // fix directfb's abuse of an enum as a bitfield, allowed in C, not C++
37 dsc.flags = static_cast<DFBSurfaceDescriptionFlags>(DSDESC_CAPS |
38 DSDESC_WIDTH |
39 DSDESC_HEIGHT |
40 DSDESC_PIXELFORMAT);
41 dsc.caps = DSCAPS_NONE; // not sure this is necessary
42 dsc.width = arg_size.width();
43 dsc.height = arg_size.height();
44 }
45
46 // Default (on Linux) seems to be RGB32, force it to ARGB so as to be
47 // compatible with chrome
48 // and we won't have to convert pixels.
49 dsc.pixelformat = DSPF_ARGB;
50
51 DFBResult err = arg_plane->dfb()->CreateSurface(arg_plane->dfb(), &dsc,
52 &internal_surface_);
53 if (err != DFB_OK) {
54 LOG(FATAL) << "Create surface failed, err = " << DirectFBErrorString(err);
55 }
56
57 if (primary_) {
58 // Do some sanity non-fatal sanity checks for primary surface.
59 // These shouldn't fail and it isn't clear how we can recover.
60 DFBSurfacePixelFormat pixelformat;
61 err = internal_surface_->GetPixelFormat(internal_surface_, &pixelformat);
62 if (err != DFB_OK) {
63 LOG(FATAL) << "GetPixelFormat failed, err = "
64 << DirectFBErrorString(err);
65 } else if (pixelformat != DSPF_ARGB) {
66 LOG(FATAL) << "Pixel format not DSPF_ARGB, err = "
67 << DirectFBErrorString(err);
68 }
69
70 // Reset size.
71 int width = 0;
72 int height = 0;
73 err = internal_surface_->GetSize(internal_surface_, &width, &height);
74 if (err != DFB_OK) {
75 LOG(FATAL) << "GetSize failed, err = " << DirectFBErrorString(err);
76 } else if (width <= 0 || height <= 0) {
77 LOG(FATAL) << "GetSize didn't return a positive screen size, err = "
78 << DirectFBErrorString(err);
79 }
80 set_size(Size(width, height));
81 }
82 }
83
84 SurfaceDirectFb::~SurfaceDirectFb() {
85 internal_surface_->Release(internal_surface_);
86 }
87
88 void SurfaceDirectFb::Blit(Surface* e_src_surface,
89 const Rect& src_rect,
90 const Point& dst_point) {
91 SurfaceDirectFb* src_surface = static_cast<SurfaceDirectFb*>(e_src_surface);
92
93 DFBRectangle dfb_src_rect;
94 dfb_src_rect.x = src_rect.x();
95 dfb_src_rect.y = src_rect.y();
96 dfb_src_rect.w = src_rect.width();
97 dfb_src_rect.h = src_rect.height();
98
99 DFBResult err = internal_surface_->Blit(
100 internal_surface_, src_surface->internal_surface_, &dfb_src_rect,
101 dst_point.x(), dst_point.y());
102 if (err != DFB_OK) {
103 LOG(FATAL) << "Blit failed, err = " << DirectFBErrorString(err);
104 }
105 }
106
107 void SurfaceDirectFb::Composite(Surface* e_src_surface,
108 const Rect& src_rect,
109 const Point& dst_point) {
110 // TODO(byungchul): To be perfect, surface for OSD should set this flag
111 // permanently. Considering this implementation is for testing on x86,
112 // setting flag here is just to keep consistency with marvell implementation.
113 internal_surface_->SetBlittingFlags(internal_surface_,
114 DSBLIT_BLEND_ALPHACHANNEL);
115 Blit(e_src_surface, src_rect, dst_point);
116 internal_surface_->SetBlittingFlags(internal_surface_, DSBLIT_NOFX);
117 }
118
119 void SurfaceDirectFb::CopyBitmap(char* src_bitmap,
120 const Rect& src_rect,
121 const Rect& damage_rect,
122 const Point& dst_point) {
123 std::vector<Rect> damage_rect_vector;
124 damage_rect_vector.push_back(damage_rect);
125
126 std::vector<Point> dst_point_vector;
127 dst_point_vector.push_back(dst_point);
128
129 BatchCopyBitmap(src_bitmap, src_rect, damage_rect_vector, dst_point_vector);
130 }
131
132 void SurfaceDirectFb::BatchCopyBitmap(
133 char* src_bitmap,
134 const Rect& src_rect,
135 const std::vector<Rect>& damage_rect_vector,
136 const std::vector<Point>& dst_point_vector) {
137 DCHECK_EQ(damage_rect_vector.size(), dst_point_vector.size());
138
139 // Note: use dynamic arrays (gcc extension) so we don't
140 // have to malloc / free space.
141 DFBRectangle src_rects[damage_rect_vector.size()];
142 DFBPoint dst_points[damage_rect_vector.size()];
143 int max_height = 0;
144 for (size_t i = 0; i < damage_rect_vector.size(); ++i) {
145 src_rects[i].x = damage_rect_vector[i].x();
146 src_rects[i].y = damage_rect_vector[i].y();
147 src_rects[i].w = damage_rect_vector[i].width();
148 src_rects[i].h = damage_rect_vector[i].height();
149 dst_points[i].x = dst_point_vector[i].x();
150 dst_points[i].y = dst_point_vector[i].y();
151 if (max_height < damage_rect_vector[i].height()) {
152 max_height = damage_rect_vector[i].height();
153 }
154 };
155
156 DCHECK_LE(max_height, src_rect.height());
157
158 // Creates a tempory surface for source bitmap.
159 DFBSurfaceDescription dsc;
160 // fix directfb's abuse of an enum as a bitfield, allowed in C, not C++
161 dsc.flags = static_cast<DFBSurfaceDescriptionFlags>(DSDESC_CAPS |
162 DSDESC_WIDTH |
163 DSDESC_HEIGHT |
164 DSDESC_PIXELFORMAT |
165 DSDESC_PREALLOCATED);
166 dsc.caps = DSCAPS_NONE; // not sure this is necessary
167 dsc.width = src_rect.width();
168 dsc.height = src_rect.height();
169 dsc.pixelformat = DSPF_ARGB; // Assume 32-bit ARGB pixels
170 dsc.preallocated[0].data = src_bitmap;
171 dsc.preallocated[0].pitch = src_rect.width() * kBytesPerPixelOfARGB;
172 dsc.preallocated[1].data = NULL; // back buffer, not provided
173 dsc.preallocated[1].pitch = 0;
174
175 IDirectFB* dfb = static_cast<GfxPlaneDirectFb*>(plane())->dfb();
176 IDirectFBSurface* src_surface = NULL;
177 DFBResult err = dfb->CreateSurface(dfb, &dsc, &src_surface);
178 if (err != DFB_OK) {
179 LOG(FATAL) << "Create surface failed, err = " << DirectFBErrorString(err);
180 }
181
182 err = internal_surface_->BatchBlit(internal_surface_, src_surface, src_rects,
183 dst_points, damage_rect_vector.size());
184 if (err != DFB_OK) {
185 LOG(FATAL) << "BatchBlit failed, err = " << DirectFBErrorString(err);
186 // falling through to release the surface and it does no harm to flip.
187 }
188
189 src_surface->Release(src_surface);
190 }
191
192 void SurfaceDirectFb::Fill(const Rect& rect, int argb) {
193 NOTIMPLEMENTED();
194 }
195
196 void SurfaceDirectFb::Display(const Rect& rect,
197 const Point& frame_buffer_point) {
198 plane()->Display(this, rect, frame_buffer_point);
199
200 // Double buffering shouldn't be necessary when running under X11
201 // (we should do it anyway for consistency and debugging).
202 //
203 // If running directfb under X11 and we are single-buffered,
204 // a flip is still needed. When running on the target and
205 // single-buffered, no flip is needed (but shouldn't hurt).
206 //
207 // An alternative to flipping here when single buffered is
208 // to allow directfb to create a flipping thread.
209 IDirectFBSurface* primary =
210 static_cast<SurfaceDirectFb*>(plane()->frame_buffer())->internal_surface_;
211 DFBResult err = primary->Flip(primary, NULL,
212 #if defined(DOUBLE_BUFFER)
213 DSFLIP_WAITFORSYNC
214 #else
215 DSFLIP_NONE
216 #endif
217 );
218 if (err != DFB_OK) {
219 LOG(FATAL) << "Flip failed, err = " << DirectFBErrorString(err);
220 return;
221 }
222
223 #if defined(DOUBLE_BUFFER)
224 // After a flip, we need to write the data again to the now stale back
225 // buffer (this makes it identical to the currently displayed front buffer.
226 plane()->Display(this, rect, frame_buffer_point);
227 #endif
228 }
229
230 } // namespace chromecast
231 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698