| Index: chromecast/ui/gfx/gfx_plane_directfb.cc
|
| diff --git a/chromecast/ui/gfx/gfx_plane_directfb.cc b/chromecast/ui/gfx/gfx_plane_directfb.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9e509ac1b886f5ce0451dd04981655f3334b3e18
|
| --- /dev/null
|
| +++ b/chromecast/ui/gfx/gfx_plane_directfb.cc
|
| @@ -0,0 +1,181 @@
|
| +// 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/gfx_plane_directfb.h"
|
| +
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "chromecast/ui/gfx/surface_directfb.h"
|
| +#include "ui/gfx/rect.h"
|
| +#include "ui/gfx/size.h"
|
| +
|
| +namespace gfx {
|
| +namespace chromecast {
|
| +
|
| +// DirectFB on X11 notes:
|
| +//
|
| +// 1. There is a thread created at launch to intercept X11 input events
|
| +// "x11EventThread".
|
| +//
|
| +// 2. If you close a window created by DirectFB on X11 (via mouse), and
|
| +// continue to do directfb calls, the program will crash:
|
| +//
|
| +// XIO: fatal IO error 11 (Resource temporarily unavailable) ...
|
| +// after 333 requests (301 known processed) with 0 events ...
|
| +// (!!!) *** WARNING [Application exited without deinitialization ...
|
| +// Segmentation fault
|
| +//
|
| +// This should normally be handled by the X11EventThread. It should
|
| +// receive a WM_DELETE_WINDOW (from X11) and post a directfb event
|
| +// DWET_CLOSE or DWET_DESTROYED. This should in turn be handled by a directfb
|
| +// event listener loop (which we could implement).
|
| +//
|
| +// Unfortunately, in DFB 1.2, the X11Eventthread only seems to handle and pass
|
| +// on key and mouse events. So, we are stuck with program crashes when a user
|
| +// closes a window (unless we want to write our own X11 listener or fix DFB).
|
| +//
|
| +GfxPlaneDirectFb::GfxPlaneDirectFb(const base::CommandLine& command_line) {
|
| + const std::vector<std::string>& args = command_line.argv();
|
| + int argc = args.size();
|
| + scoped_ptr<char *[]> argv(new char *[argc + 1]);
|
| + for (size_t i = 0; i < args.size(); ++i) {
|
| + argv[i] = strdup(args[i].c_str());
|
| + }
|
| + argv[argc] = NULL;
|
| + char **argv_pointer = argv.get();
|
| +
|
| + // using a copy of arguments so they aren't modified.
|
| +
|
| + // Note: DirectFBInit *will* modify the arguments
|
| +
|
| + // Note: there are lots of DFB arguments
|
| + // see --dfb-help for list
|
| + // pass them via --dfb:<option>[,<option>]
|
| + // ex: session=0 (MVGFX on Marvell)
|
| + // mode=1920x1080 (not needed)
|
| + DFBResult err = DirectFBInit(&argc, &argv_pointer);
|
| +
|
| + for (size_t i = 0; i < args.size(); ++i) {
|
| + free(argv[i]);
|
| + }
|
| +
|
| + if (err != DFB_OK) { // test err from init above
|
| + LOG(FATAL) << "DirectFBInit failed, err = " << DirectFBErrorString(err);
|
| + }
|
| +
|
| + // When single-buffered, and we set this option:
|
| + //
|
| + // DirectFBSetOption ("autoflip-window", NULL);
|
| + //
|
| + // Directfb will create a "Flipping Thread". We'll just flip outselves
|
| + // and save the overhead. This will emit an error which we can ignore:
|
| + //
|
| + // (!!!) *** WARNING [Non-flipping window surface and no ...
|
| + // 'autoflip-window' option used] ***
|
| +
|
| + err = DirectFBCreate(&dfb_);
|
| + if (err != DFB_OK) {
|
| + LOG(FATAL) << "DirectFBCreate failed, err = " << DirectFBErrorString(err);
|
| + }
|
| +
|
| + err = dfb_->SetCooperativeLevel(dfb_,
|
| +#if defined(__arm__)
|
| + DFSCL_EXCLUSIVE
|
| +#else
|
| + DFSCL_FULLSCREEN
|
| +#endif
|
| + );
|
| + if (err != DFB_OK) {
|
| +#if defined(__arm__)
|
| + LOG(FATAL)
|
| +#else
|
| + LOG(WARNING)
|
| +#endif
|
| + << "Set EXCLUSIVE/FULLSCREEN failed, err = "
|
| + << DirectFBErrorString(err);
|
| + }
|
| +}
|
| +
|
| +// Shutdown directfb. Under X11, this will also close the window.
|
| +//
|
| +// These messages may appear on the console:
|
| +//
|
| +// (!!!) *** WARNING [still objects in 'GraphicsState Pool'] *** ...
|
| +// (!!!) *** WARNING [still objects in 'Surface Pool'] *** ...
|
| +//
|
| +
|
| +// Note2: This function crashes under DFB 1.2.8 on Linux due to memory
|
| +// corruption. Valgind shows there are multiple malloc/free problems with
|
| +// DFB 1.2.8. DFB 1.5.3 runs cleanly with valgrind (and doesn't crash).
|
| +GfxPlaneDirectFb::~GfxPlaneDirectFb() {
|
| + set_frame_buffer(NULL); // Release frame buffer here before closing DFB.
|
| + dfb_->Release(dfb_);
|
| +}
|
| +
|
| +Surface* GfxPlaneDirectFb::CreateSurface(const gfx::Size& arg_size) {
|
| + return new SurfaceDirectFb(this, arg_size, false);
|
| +}
|
| +
|
| +// static
|
| +GfxPlane* GfxPlane::CreatePrimary(const base::CommandLine& command_line,
|
| + const Size& requested_screen_size) {
|
| +#if defined(__arm__)
|
| + CHECK(!primary_);
|
| +#else
|
| + // On x86, we don't destroy gfx plane because directfd crashes.
|
| + if (primary_) return primary_;
|
| +#endif
|
| +
|
| + GfxPlaneDirectFb* directfb = new GfxPlaneDirectFb(command_line);
|
| + directfb->set_frame_buffer(
|
| + new SurfaceDirectFb(directfb, directfb->size(), true));
|
| +
|
| + primary_ = directfb;
|
| + return primary_;
|
| +}
|
| +
|
| +// static
|
| +void GfxPlane::DestroyPrimary() {
|
| + CHECK(primary_);
|
| +#if defined(__arm__)
|
| + delete primary_;
|
| + // primary_ = NULL; already reset by dtor().
|
| +#endif
|
| +}
|
| +
|
| +// static
|
| +GfxPlane* GfxPlane::CreateOsdPlane() {
|
| + // Use primary gfx plane for OSD.
|
| + // Do nothing here.
|
| + return primary_;
|
| +}
|
| +
|
| +// static
|
| +void GfxPlane::DestroyOsdPlane() {
|
| + // Use primary gfx plane for OSD.
|
| + // Do nothing here.
|
| +}
|
| +
|
| +// static
|
| +GfxPlane* GfxPlane::GetOsdPlane() {
|
| + return primary_;
|
| +}
|
| +
|
| +// static
|
| +void GfxPlane::ResizeOsdPlane(const Size& size) {
|
| + // Use primary gfx plane for OSD.
|
| + // Do nothing here.
|
| +}
|
| +
|
| +// static
|
| +bool GfxPlane::Is1080pAllowed() {
|
| + return true;
|
| +}
|
| +
|
| +} // namespace chromecast
|
| +} // namespace gfx
|
|
|