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

Unified 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, 9 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 side-by-side diff with in-line comments
Download patch
Index: chromecast/ui/gfx/surface_directfb.cc
diff --git a/chromecast/ui/gfx/surface_directfb.cc b/chromecast/ui/gfx/surface_directfb.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2b4e16374c2c27f8ede6b25c5e27b3fdc5210427
--- /dev/null
+++ b/chromecast/ui/gfx/surface_directfb.cc
@@ -0,0 +1,231 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/ui/gfx/surface_directfb.h"
+
+#include "base/logging.h"
+#include "chromecast/ui/gfx/gfx_plane_directfb.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/size.h"
+
+namespace gfx {
+namespace chromecast {
+
+SurfaceDirectFb::SurfaceDirectFb(GfxPlaneDirectFb* arg_plane,
+ const Size& arg_size, bool arg_primary)
+ : Surface(arg_plane, arg_size),
+ primary_(arg_primary) {
+ DFBSurfaceDescription dsc;
+
+ if (primary_) {
+ // fix directfb's abuse of an enum as a bitfield, allowed in C, not C++
+ dsc.flags = static_cast<DFBSurfaceDescriptionFlags>(DSDESC_CAPS |
+ DSDESC_PIXELFORMAT);
+#if defined(DOUBLE_BUFFER)
+ dsc.caps = static_cast<DFBSurfaceCapabilities>(DSCAPS_PRIMARY |
+ DSCAPS_DOUBLE);
+#else
+ dsc.caps = DSCAPS_PRIMARY;
+ // Add DSCAPS_DOUBLE to double-buffer, and if so, we'll need to disable
+ // autoflip-window, and explictly call Flip.
+ //
+#endif
+ } else {
+ // fix directfb's abuse of an enum as a bitfield, allowed in C, not C++
+ dsc.flags = static_cast<DFBSurfaceDescriptionFlags>(DSDESC_CAPS |
+ DSDESC_WIDTH |
+ DSDESC_HEIGHT |
+ DSDESC_PIXELFORMAT);
+ dsc.caps = DSCAPS_NONE; // not sure this is necessary
+ dsc.width = arg_size.width();
+ dsc.height = arg_size.height();
+ }
+
+ // Default (on Linux) seems to be RGB32, force it to ARGB so as to be
+ // compatible with chrome
+ // and we won't have to convert pixels.
+ dsc.pixelformat = DSPF_ARGB;
+
+ DFBResult err = arg_plane->dfb()->CreateSurface(arg_plane->dfb(), &dsc,
+ &internal_surface_);
+ if (err != DFB_OK) {
+ LOG(FATAL) << "Create surface failed, err = " << DirectFBErrorString(err);
+ }
+
+ if (primary_) {
+ // Do some sanity non-fatal sanity checks for primary surface.
+ // These shouldn't fail and it isn't clear how we can recover.
+ DFBSurfacePixelFormat pixelformat;
+ err = internal_surface_->GetPixelFormat(internal_surface_, &pixelformat);
+ if (err != DFB_OK) {
+ LOG(FATAL) << "GetPixelFormat failed, err = "
+ << DirectFBErrorString(err);
+ } else if (pixelformat != DSPF_ARGB) {
+ LOG(FATAL) << "Pixel format not DSPF_ARGB, err = "
+ << DirectFBErrorString(err);
+ }
+
+ // Reset size.
+ int width = 0;
+ int height = 0;
+ err = internal_surface_->GetSize(internal_surface_, &width, &height);
+ if (err != DFB_OK) {
+ LOG(FATAL) << "GetSize failed, err = " << DirectFBErrorString(err);
+ } else if (width <= 0 || height <= 0) {
+ LOG(FATAL) << "GetSize didn't return a positive screen size, err = "
+ << DirectFBErrorString(err);
+ }
+ set_size(Size(width, height));
+ }
+}
+
+SurfaceDirectFb::~SurfaceDirectFb() {
+ internal_surface_->Release(internal_surface_);
+}
+
+void SurfaceDirectFb::Blit(Surface* e_src_surface,
+ const Rect& src_rect,
+ const Point& dst_point) {
+ SurfaceDirectFb* src_surface = static_cast<SurfaceDirectFb*>(e_src_surface);
+
+ DFBRectangle dfb_src_rect;
+ dfb_src_rect.x = src_rect.x();
+ dfb_src_rect.y = src_rect.y();
+ dfb_src_rect.w = src_rect.width();
+ dfb_src_rect.h = src_rect.height();
+
+ DFBResult err = internal_surface_->Blit(
+ internal_surface_, src_surface->internal_surface_, &dfb_src_rect,
+ dst_point.x(), dst_point.y());
+ if (err != DFB_OK) {
+ LOG(FATAL) << "Blit failed, err = " << DirectFBErrorString(err);
+ }
+}
+
+void SurfaceDirectFb::Composite(Surface* e_src_surface,
+ const Rect& src_rect,
+ const Point& dst_point) {
+ // TODO(byungchul): To be perfect, surface for OSD should set this flag
+ // permanently. Considering this implementation is for testing on x86,
+ // setting flag here is just to keep consistency with marvell implementation.
+ internal_surface_->SetBlittingFlags(internal_surface_,
+ DSBLIT_BLEND_ALPHACHANNEL);
+ Blit(e_src_surface, src_rect, dst_point);
+ internal_surface_->SetBlittingFlags(internal_surface_, DSBLIT_NOFX);
+}
+
+void SurfaceDirectFb::CopyBitmap(char* src_bitmap,
+ const Rect& src_rect,
+ const Rect& damage_rect,
+ const Point& dst_point) {
+ std::vector<Rect> damage_rect_vector;
+ damage_rect_vector.push_back(damage_rect);
+
+ std::vector<Point> dst_point_vector;
+ dst_point_vector.push_back(dst_point);
+
+ BatchCopyBitmap(src_bitmap, src_rect, damage_rect_vector, dst_point_vector);
+}
+
+void SurfaceDirectFb::BatchCopyBitmap(
+ char* src_bitmap,
+ const Rect& src_rect,
+ const std::vector<Rect>& damage_rect_vector,
+ const std::vector<Point>& dst_point_vector) {
+ DCHECK_EQ(damage_rect_vector.size(), dst_point_vector.size());
+
+ // Note: use dynamic arrays (gcc extension) so we don't
+ // have to malloc / free space.
+ DFBRectangle src_rects[damage_rect_vector.size()];
+ DFBPoint dst_points[damage_rect_vector.size()];
+ int max_height = 0;
+ for (size_t i = 0; i < damage_rect_vector.size(); ++i) {
+ src_rects[i].x = damage_rect_vector[i].x();
+ src_rects[i].y = damage_rect_vector[i].y();
+ src_rects[i].w = damage_rect_vector[i].width();
+ src_rects[i].h = damage_rect_vector[i].height();
+ dst_points[i].x = dst_point_vector[i].x();
+ dst_points[i].y = dst_point_vector[i].y();
+ if (max_height < damage_rect_vector[i].height()) {
+ max_height = damage_rect_vector[i].height();
+ }
+ };
+
+ DCHECK_LE(max_height, src_rect.height());
+
+ // Creates a tempory surface for source bitmap.
+ DFBSurfaceDescription dsc;
+ // fix directfb's abuse of an enum as a bitfield, allowed in C, not C++
+ dsc.flags = static_cast<DFBSurfaceDescriptionFlags>(DSDESC_CAPS |
+ DSDESC_WIDTH |
+ DSDESC_HEIGHT |
+ DSDESC_PIXELFORMAT |
+ DSDESC_PREALLOCATED);
+ dsc.caps = DSCAPS_NONE; // not sure this is necessary
+ dsc.width = src_rect.width();
+ dsc.height = src_rect.height();
+ dsc.pixelformat = DSPF_ARGB; // Assume 32-bit ARGB pixels
+ dsc.preallocated[0].data = src_bitmap;
+ dsc.preallocated[0].pitch = src_rect.width() * kBytesPerPixelOfARGB;
+ dsc.preallocated[1].data = NULL; // back buffer, not provided
+ dsc.preallocated[1].pitch = 0;
+
+ IDirectFB* dfb = static_cast<GfxPlaneDirectFb*>(plane())->dfb();
+ IDirectFBSurface* src_surface = NULL;
+ DFBResult err = dfb->CreateSurface(dfb, &dsc, &src_surface);
+ if (err != DFB_OK) {
+ LOG(FATAL) << "Create surface failed, err = " << DirectFBErrorString(err);
+ }
+
+ err = internal_surface_->BatchBlit(internal_surface_, src_surface, src_rects,
+ dst_points, damage_rect_vector.size());
+ if (err != DFB_OK) {
+ LOG(FATAL) << "BatchBlit failed, err = " << DirectFBErrorString(err);
+ // falling through to release the surface and it does no harm to flip.
+ }
+
+ src_surface->Release(src_surface);
+}
+
+void SurfaceDirectFb::Fill(const Rect& rect, int argb) {
+ NOTIMPLEMENTED();
+}
+
+void SurfaceDirectFb::Display(const Rect& rect,
+ const Point& frame_buffer_point) {
+ plane()->Display(this, rect, frame_buffer_point);
+
+ // Double buffering shouldn't be necessary when running under X11
+ // (we should do it anyway for consistency and debugging).
+ //
+ // If running directfb under X11 and we are single-buffered,
+ // a flip is still needed. When running on the target and
+ // single-buffered, no flip is needed (but shouldn't hurt).
+ //
+ // An alternative to flipping here when single buffered is
+ // to allow directfb to create a flipping thread.
+ IDirectFBSurface* primary =
+ static_cast<SurfaceDirectFb*>(plane()->frame_buffer())->internal_surface_;
+ DFBResult err = primary->Flip(primary, NULL,
+#if defined(DOUBLE_BUFFER)
+ DSFLIP_WAITFORSYNC
+#else
+ DSFLIP_NONE
+#endif
+ );
+ if (err != DFB_OK) {
+ LOG(FATAL) << "Flip failed, err = " << DirectFBErrorString(err);
+ return;
+ }
+
+#if defined(DOUBLE_BUFFER)
+ // After a flip, we need to write the data again to the now stale back
+ // buffer (this makes it identical to the currently displayed front buffer.
+ plane()->Display(this, rect, frame_buffer_point);
+#endif
+}
+
+} // namespace chromecast
+} // namespace gfx

Powered by Google App Engine
This is Rietveld 408576698