<commit_before>/*
 * Copyright 2015 Cloudius Systems
 */
#include "mutation.hh"
#include "sstables.hh"
#include "types.hh"
#include "core/future-util.hh"
#include "key.hh"
#include "keys.hh"
#include "core/do_with.hh"
#include "unimplemented.hh"

#include "dht/i_partitioner.hh"

namespace sstables {

/**
 * @returns: >= 0, if key is found. That is the index where the key is found.
 *             -1, if key is not found, and is smaller than the first key in the list.
 *          <= -2, if key is not found, but is greater than one of the keys. By adding 2 and
 *                 negating, one can determine the index before which the key would have to
 *                 be inserted.
 *
 * Origin uses this slightly modified binary search for the Summary, that will
 * indicate in which bucket the element would be in case it is not a match.
 *
 * For the Index entries, it uses a "normal", java.lang binary search. Because
 * we have made the explicit decision to open code the comparator for
 * efficiency, using a separate binary search would be possible, but very
 * messy.
 *
 * It's easier to reuse the same code for both binary searches, and just ignore
 * the extra information when not needed.
 *
 * This code should work in all kinds of vectors in whose's elements is possible to aquire
 * a key view.
 */
template <typename T>
int sstable::binary_search(const T& entries, const key& sk, const dht::token& token) {
    int low = 0, mid = entries.size(), high = mid - 1, result = -1;

    auto& partitioner = dht::global_partitioner();
    auto sk_bytes = bytes_view(sk);

    while (low <= high) {
        // The token comparison should yield the right result most of the time.
        // So we avoid expensive copying operations that happens at key
        // creation by keeping only a key view, and then manually carrying out
        // both parts of the comparison ourselves.
        mid = low + ((high - low) >> 1);
        auto mid_bytes = bytes_view(entries[mid]);
        auto mid_key = key_view(mid_bytes);
        auto mid_token = partitioner.get_token(mid_key);

        if (token == mid_token) {
            result = compare_unsigned(sk_bytes, mid_bytes);
        } else {
            result = token < mid_token ? -1 : 1;
        }

        if (result > 0) {
            low = mid + 1;
        } else if (result < 0) {
            high = mid - 1;
        } else {
            return mid;
        }
    }

    return -mid - (result < 0 ? 1 : 2);
}

// Force generation, so we make it available outside this compilation unit without moving that
// much code to .hh
template int sstable::binary_search<>(const std::vector<summary_entry>& entries, const key& sk);
template int sstable::binary_search<>(const std::vector<index_entry>& entries, const key& sk);

class mp_row_consumer : public row_consumer {
    schema_ptr _schema;
    key _key;

    struct column {
        bool is_static;
        bytes_view col_name;
        std::vector<bytes> clustering;
        bytes cell;
        const column_definition *cdef;

        static constexpr size_t static_size = 2;

        static bool check_static(bytes_view col) {
            static bytes static_row(static_size, 0xff);
            return col.compare(0, static_size, static_row) == 0;
        }

        static bytes_view fix_static_name(bytes_view col) {
            if (check_static(col)) {
                col.remove_prefix(static_size);
            }
            return col;
        }

        column(const schema& schema, bytes_view col)
            : is_static(check_static(col))
            , col_name(fix_static_name(col))
            , clustering(composite_view(col_name).explode())
            , cell(std::move(clustering.back()))
            , cdef(schema.get_column_definition(cell))
        {

            if (is_static) {
                for (auto& e: clustering) {
                    if (e.size() != 0) {
                        throw malformed_sstable_exception("Static row has clustering key information. I didn't expect that!");
                    }
                }
            }

            if (cell.size() && !cdef) {
                throw malformed_sstable_exception(sprint("schema does not contain column: %s", cell.c_str()));
            }

            clustering.pop_back();
        }
    };
public:
    mutation mut;

    mp_row_consumer(const key& key, const schema_ptr _schema)
            : _schema(_schema)
            , _key(key)
            , mut(partition_key::from_exploded(*_schema, key.explode(*_schema)), _schema)
    { }

    void validate_row_marker() {
        if (_schema->is_dense()) {
            throw malformed_sstable_exception("row marker found in dense table");
        }
    }

    virtual void consume_row_start(sstables::key_view key, sstables::deletion_time deltime) override {
        // FIXME: We should be doing more than that: We need to check the deletion time and propagate the tombstone information
        key_view k(_key);
        if (key != k) {
            throw malformed_sstable_exception(sprint("Key mismatch. Got %s while processing %s", to_hex(bytes_view(key)).c_str(), to_hex(bytes_view(k)).c_str()));
        }
    }

    atomic_cell make_atomic_cell(uint64_t timestamp, bytes_view value, uint32_t ttl, uint32_t expiration) {
        if (ttl) {
            return atomic_cell::make_live(timestamp, value,
                gc_clock::time_point(gc_clock::duration(expiration)), gc_clock::duration(ttl));
        } else {
            return atomic_cell::make_live(timestamp, value);
        }
    }

    virtual void consume_cell(bytes_view col_name, bytes_view value, int64_t timestamp, int32_t ttl, int32_t expiration) override {
        struct column col(*_schema, col_name);

        // FIXME: collections are different, but not yet handled.
        if (col.clustering.size() > (_schema->clustering_key_type()->types().size() + 1)) {
            throw malformed_sstable_exception("wrong number of clustering columns");
        }

        auto ac = make_atomic_cell(timestamp, value, ttl, expiration);

        if (col.is_static) {
            mut.set_static_cell(*(col.cdef), std::move(ac));
            return;
        }

        auto clustering_prefix = exploded_clustering_prefix(std::move(col.clustering));

        if (col.cell.size() == 0) {
            auto clustering_key = clustering_key::from_clustering_prefix(*_schema, clustering_prefix);
            auto& dr = mut.partition().clustered_row(clustering_key);
            dr.apply(timestamp);
            return;
        }

        mut.set_cell(clustering_prefix, *(col.cdef), atomic_cell_or_collection(std::move(ac)));
    }

    virtual void consume_deleted_cell(bytes_view col_name, sstables::deletion_time deltime) override {
        struct column col(*_schema, col_name);
        gc_clock::duration secs(deltime.local_deletion_time);

        consume_deleted_cell(col, deltime.marked_for_delete_at, gc_clock::time_point(secs));
    }

    void consume_deleted_cell(column &col, int64_t timestamp, gc_clock::time_point ttl) {
        auto ac = atomic_cell::make_dead(timestamp, ttl);

        if (col.is_static) {
            mut.set_static_cell(*(col.cdef), atomic_cell_or_collection(std::move(ac)));
        } else {
            auto clustering_prefix = exploded_clustering_prefix(std::move(col.clustering));
            mut.set_cell(clustering_prefix, *(col.cdef), atomic_cell_or_collection(std::move(ac)));
        }
    }
    virtual void consume_row_end() override {
    }

    virtual void consume_range_tombstone(
            bytes_view start_col, bytes_view end_col,
            sstables::deletion_time deltime) override {
        check_marker(start_col, composite_marker::start_range);
        check_marker(end_col, composite_marker::end_range);

        // FIXME: CASSANDRA-6237 says support will be added to things like this.
        //
        // The check below represents a range with a different start and end
        // clustering key.  Cassandra-generated files (to the moment) will
        // generate multi-row deletes, but they always have the same clustering
        // key. This is basically because one can't (yet) write delete
        // statements in which the WHERE clause looks like WHERE clustering_key >= x.
        //
        // We don't really have it in our model ATM, so let's just mark this unimplemented.
        //
        // The only expected difference between them, is the final marker. We
        // will remove it from end_col to ease the comparison, but will leave
        // start_col untouched to make sure explode() still works.
        end_col.remove_suffix(1);
        if (start_col.compare(0, end_col.size(), end_col)) {
            fail(unimplemented::cause::RANGE_DELETES);
        }

        auto start = composite_view(column::fix_static_name(start_col)).explode();
        if (start.size() <= _schema->clustering_key_size()) {
            mut.partition().apply_delete(*_schema, exploded_clustering_prefix(std::move(start)), tombstone(deltime));
        } else {
            throw runtime_exception("Collections not implemented");
        }
    }
};

future<mutation_opt>
sstables::sstable::convert_row(schema_ptr schema, const sstables::key& key) {

    assert(schema);

    auto& partitioner = dht::global_partitioner();
    auto token = partitioner.get_token(key_view(key));

    if (!filter_has_key(token)) {
        return make_ready_future<mutation_opt>();
    }

    auto& summary = _summary;
    auto summary_idx = binary_search(summary.entries, key, token);
    if (summary_idx < 0) {
        // binary search gives us the first index _greater_ than the key searched for,
        // i.e., its insertion position
        auto gt = (summary_idx + 1) * -1;
        summary_idx = gt - 1;
    }
    if (summary_idx < 0) {
        return make_ready_future<mutation_opt>();
    }

    auto position = _summary.entries[summary_idx].position;
    return read_indexes(position).then([this, schema, &key, token] (auto index_list) {
        auto index_idx = this->binary_search(index_list, key, token);
        if (index_idx < 0) {
            return make_ready_future<mutation_opt>();
        }

        auto position = index_list[index_idx].position;
        size_t end;
        if (size_t(index_idx + 1) < index_list.size()) {
            end = index_list[index_idx + 1].position;
        } else {
            end = this->data_size();
        }

        return do_with(mp_row_consumer(key, schema), [this, position, end] (auto& c) {
            return this->data_consume_rows_at_once(c, position, end).then([&c] {
                return make_ready_future<mutation_opt>(std::move(c.mut));
            });
        });
    });
}
}
<commit_msg>sstables: handle row tombstone<commit_after>/*
 * Copyright 2015 Cloudius Systems
 */
#include "mutation.hh"
#include "sstables.hh"
#include "types.hh"
#include "core/future-util.hh"
#include "key.hh"
#include "keys.hh"
#include "core/do_with.hh"
#include "unimplemented.hh"

#include "dht/i_partitioner.hh"

namespace sstables {

/**
 * @returns: >= 0, if key is found. That is the index where the key is found.
 *             -1, if key is not found, and is smaller than the first key in the list.
 *          <= -2, if key is not found, but is greater than one of the keys. By adding 2 and
 *                 negating, one can determine the index before which the key would have to
 *                 be inserted.
 *
 * Origin uses this slightly modified binary search for the Summary, that will
 * indicate in which bucket the element would be in case it is not a match.
 *
 * For the Index entries, it uses a "normal", java.lang binary search. Because
 * we have made the explicit decision to open code the comparator for
 * efficiency, using a separate binary search would be possible, but very
 * messy.
 *
 * It's easier to reuse the same code for both binary searches, and just ignore
 * the extra information when not needed.
 *
 * This code should work in all kinds of vectors in whose's elements is possible to aquire
 * a key view.
 */
template <typename T>
int sstable::binary_search(const T& entries, const key& sk, const dht::token& token) {
    int low = 0, mid = entries.size(), high = mid - 1, result = -1;

    auto& partitioner = dht::global_partitioner();
    auto sk_bytes = bytes_view(sk);

    while (low <= high) {
        // The token comparison should yield the right result most of the time.
        // So we avoid expensive copying operations that happens at key
        // creation by keeping only a key view, and then manually carrying out
        // both parts of the comparison ourselves.
        mid = low + ((high - low) >> 1);
        auto mid_bytes = bytes_view(entries[mid]);
        auto mid_key = key_view(mid_bytes);
        auto mid_token = partitioner.get_token(mid_key);

        if (token == mid_token) {
            result = compare_unsigned(sk_bytes, mid_bytes);
        } else {
            result = token < mid_token ? -1 : 1;
        }

        if (result > 0) {
            low = mid + 1;
        } else if (result < 0) {
            high = mid - 1;
        } else {
            return mid;
        }
    }

    return -mid - (result < 0 ? 1 : 2);
}

// Force generation, so we make it available outside this compilation unit without moving that
// much code to .hh
template int sstable::binary_search<>(const std::vector<summary_entry>& entries, const key& sk);
template int sstable::binary_search<>(const std::vector<index_entry>& entries, const key& sk);

class mp_row_consumer : public row_consumer {
    schema_ptr _schema;
    key _key;

    struct column {
        bool is_static;
        bytes_view col_name;
        std::vector<bytes> clustering;
        bytes cell;
        const column_definition *cdef;

        static constexpr size_t static_size = 2;

        static bool check_static(bytes_view col) {
            static bytes static_row(static_size, 0xff);
            return col.compare(0, static_size, static_row) == 0;
        }

        static bytes_view fix_static_name(bytes_view col) {
            if (check_static(col)) {
                col.remove_prefix(static_size);
            }
            return col;
        }

        column(const schema& schema, bytes_view col)
            : is_static(check_static(col))
            , col_name(fix_static_name(col))
            , clustering(composite_view(col_name).explode())
            , cell(std::move(clustering.back()))
            , cdef(schema.get_column_definition(cell))
        {

            if (is_static) {
                for (auto& e: clustering) {
                    if (e.size() != 0) {
                        throw malformed_sstable_exception("Static row has clustering key information. I didn't expect that!");
                    }
                }
            }

            if (cell.size() && !cdef) {
                throw malformed_sstable_exception(sprint("schema does not contain column: %s", cell.c_str()));
            }

            clustering.pop_back();
        }
    };
public:
    mutation mut;

    mp_row_consumer(const key& key, const schema_ptr _schema)
            : _schema(_schema)
            , _key(key)
            , mut(partition_key::from_exploded(*_schema, key.explode(*_schema)), _schema)
    { }

    void validate_row_marker() {
        if (_schema->is_dense()) {
            throw malformed_sstable_exception("row marker found in dense table");
        }
    }

    virtual void consume_row_start(sstables::key_view key, sstables::deletion_time deltime) override {
        key_view k(_key);
        if (key != k) {
            throw malformed_sstable_exception(sprint("Key mismatch. Got %s while processing %s", to_hex(bytes_view(key)).c_str(), to_hex(bytes_view(k)).c_str()));
        }

        if (!deltime.live()) {
            mut.partition().apply(tombstone(deltime));
        }
    }

    atomic_cell make_atomic_cell(uint64_t timestamp, bytes_view value, uint32_t ttl, uint32_t expiration) {
        if (ttl) {
            return atomic_cell::make_live(timestamp, value,
                gc_clock::time_point(gc_clock::duration(expiration)), gc_clock::duration(ttl));
        } else {
            return atomic_cell::make_live(timestamp, value);
        }
    }

    virtual void consume_cell(bytes_view col_name, bytes_view value, int64_t timestamp, int32_t ttl, int32_t expiration) override {
        struct column col(*_schema, col_name);

        // FIXME: collections are different, but not yet handled.
        if (col.clustering.size() > (_schema->clustering_key_type()->types().size() + 1)) {
            throw malformed_sstable_exception("wrong number of clustering columns");
        }

        auto ac = make_atomic_cell(timestamp, value, ttl, expiration);

        if (col.is_static) {
            mut.set_static_cell(*(col.cdef), std::move(ac));
            return;
        }

        auto clustering_prefix = exploded_clustering_prefix(std::move(col.clustering));

        if (col.cell.size() == 0) {
            auto clustering_key = clustering_key::from_clustering_prefix(*_schema, clustering_prefix);
            auto& dr = mut.partition().clustered_row(clustering_key);
            dr.apply(timestamp);
            return;
        }

        mut.set_cell(clustering_prefix, *(col.cdef), atomic_cell_or_collection(std::move(ac)));
    }

    virtual void consume_deleted_cell(bytes_view col_name, sstables::deletion_time deltime) override {
        struct column col(*_schema, col_name);
        gc_clock::duration secs(deltime.local_deletion_time);

        consume_deleted_cell(col, deltime.marked_for_delete_at, gc_clock::time_point(secs));
    }

    void consume_deleted_cell(column &col, int64_t timestamp, gc_clock::time_point ttl) {
        auto ac = atomic_cell::make_dead(timestamp, ttl);

        if (col.is_static) {
            mut.set_static_cell(*(col.cdef), atomic_cell_or_collection(std::move(ac)));
        } else {
            auto clustering_prefix = exploded_clustering_prefix(std::move(col.clustering));
            mut.set_cell(clustering_prefix, *(col.cdef), atomic_cell_or_collection(std::move(ac)));
        }
    }
    virtual void consume_row_end() override {
    }

    virtual void consume_range_tombstone(
            bytes_view start_col, bytes_view end_col,
            sstables::deletion_time deltime) override {
        check_marker(start_col, composite_marker::start_range);
        check_marker(end_col, composite_marker::end_range);

        // FIXME: CASSANDRA-6237 says support will be added to things like this.
        //
        // The check below represents a range with a different start and end
        // clustering key.  Cassandra-generated files (to the moment) will
        // generate multi-row deletes, but they always have the same clustering
        // key. This is basically because one can't (yet) write delete
        // statements in which the WHERE clause looks like WHERE clustering_key >= x.
        //
        // We don't really have it in our model ATM, so let's just mark this unimplemented.
        //
        // The only expected difference between them, is the final marker. We
        // will remove it from end_col to ease the comparison, but will leave
        // start_col untouched to make sure explode() still works.
        end_col.remove_suffix(1);
        if (start_col.compare(0, end_col.size(), end_col)) {
            fail(unimplemented::cause::RANGE_DELETES);
        }

        auto start = composite_view(column::fix_static_name(start_col)).explode();
        if (start.size() <= _schema->clustering_key_size()) {
            mut.partition().apply_delete(*_schema, exploded_clustering_prefix(std::move(start)), tombstone(deltime));
        } else {
            throw runtime_exception("Collections not implemented");
        }
    }
};

future<mutation_opt>
sstables::sstable::convert_row(schema_ptr schema, const sstables::key& key) {

    assert(schema);

    auto& partitioner = dht::global_partitioner();
    auto token = partitioner.get_token(key_view(key));

    if (!filter_has_key(token)) {
        return make_ready_future<mutation_opt>();
    }

    auto& summary = _summary;
    auto summary_idx = binary_search(summary.entries, key, token);
    if (summary_idx < 0) {
        // binary search gives us the first index _greater_ than the key searched for,
        // i.e., its insertion position
        auto gt = (summary_idx + 1) * -1;
        summary_idx = gt - 1;
    }
    if (summary_idx < 0) {
        return make_ready_future<mutation_opt>();
    }

    auto position = _summary.entries[summary_idx].position;
    return read_indexes(position).then([this, schema, &key, token] (auto index_list) {
        auto index_idx = this->binary_search(index_list, key, token);
        if (index_idx < 0) {
            return make_ready_future<mutation_opt>();
        }

        auto position = index_list[index_idx].position;
        size_t end;
        if (size_t(index_idx + 1) < index_list.size()) {
            end = index_list[index_idx + 1].position;
        } else {
            end = this->data_size();
        }

        return do_with(mp_row_consumer(key, schema), [this, position, end] (auto& c) {
            return this->data_consume_rows_at_once(c, position, end).then([&c] {
                return make_ready_future<mutation_opt>(std::move(c.mut));
            });
        });
    });
}
}
<|endoftext|>


<commit_before>// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#define WL_EGL_PLATFORM

#include "fl_renderer_wayland.h"
#include "flutter/shell/platform/linux/egl_utils.h"

#include <gdk/gdkwayland.h>
#include <wayland-egl-core.h>

struct _FlRendererWayland {
  FlRenderer parent_instance;
  wl_registry* registry;
  wl_subcompositor* subcompositor;

  struct {
    wl_subsurface* subsurface;
    wl_surface* surface;
    wl_egl_window* egl_window;
    GdkRectangle geometry;
    gint scale;
  } subsurface;

  // The resource surface will not be mapped, but needs to be a wl_surface
  // because ONLY window EGL surfaces are supported on Wayland.
  struct {
    wl_surface* surface;
    wl_egl_window* egl_window;
  } resource;
};

G_DEFINE_TYPE(FlRendererWayland, fl_renderer_wayland, fl_renderer_get_type())

// wl_registry.global callback.
static void registry_handle_global(void* data,
                                   wl_registry* registry,
                                   uint32_t id,
                                   const char* name,
                                   uint32_t max_version) {
  FlRendererWayland* self = FL_RENDERER_WAYLAND(data);
  if (strcmp(name, wl_subcompositor_interface.name) == 0) {
    uint32_t version = MIN(
        static_cast<uint32_t>(wl_subcompositor_interface.version), max_version);
    self->subcompositor = static_cast<wl_subcompositor*>(
        wl_registry_bind(registry, id, &wl_subcompositor_interface, version));
  }
}

// wl_registry.global_remove callback.
// Can be safely ignored unless we bind to globals that might be removed.
static void registry_handle_global_remove(void*, wl_registry*, uint32_t) {}

static const wl_registry_listener registry_listener = {
    .global = registry_handle_global,
    .global_remove = registry_handle_global_remove,
};

// The first time this function is called, all Wayland globals are initialized
// (which blocks for a round trip to the Wayland compositor).
// Subsequent calls return immediately.
static void fl_renderer_wayland_lazy_init_wl(FlRendererWayland* self) {
  if (self->registry) {
    return;
  }

  GdkWaylandDisplay* gdk_display =
      GDK_WAYLAND_DISPLAY(gdk_display_get_default());
  g_return_if_fail(gdk_display);

  wl_display* display = gdk_wayland_display_get_wl_display(gdk_display);
  self->registry = wl_display_get_registry(display);
  wl_registry_add_listener(self->registry, &registry_listener, self);
  wl_display_roundtrip(display);
}

// Implements GObject::dispose.
static void fl_renderer_wayland_dispose(GObject* object) {
  FlRendererWayland* self = FL_RENDERER_WAYLAND(object);

  g_clear_pointer(&self->registry, wl_registry_destroy);
  g_clear_pointer(&self->subcompositor, wl_subcompositor_destroy);

  g_clear_pointer(&self->subsurface.subsurface, wl_subsurface_destroy);
  g_clear_pointer(&self->subsurface.egl_window, wl_egl_window_destroy);
  g_clear_pointer(&self->subsurface.surface, wl_surface_destroy);

  g_clear_pointer(&self->resource.egl_window, wl_egl_window_destroy);
  g_clear_pointer(&self->resource.surface, wl_surface_destroy);

  G_OBJECT_CLASS(fl_renderer_wayland_parent_class)->dispose(object);
}

// Implements FlRenderer::create_display.
static EGLDisplay fl_renderer_wayland_create_display(FlRenderer* /*renderer*/) {
  GdkWaylandDisplay* gdk_display =
      GDK_WAYLAND_DISPLAY(gdk_display_get_default());
  g_return_val_if_fail(gdk_display, nullptr);
  return eglGetDisplay(gdk_wayland_display_get_wl_display(gdk_display));
}

static void fl_renderer_wayland_on_window_map(FlRendererWayland* self,
                                              GtkWidget* widget) {
  if (self->subsurface.subsurface) {
    g_error("fl_renderer_wayland_on_window_map: already has a subsurface");
    return;
  }

  GdkWaylandDisplay* gdk_display =
      GDK_WAYLAND_DISPLAY(gdk_display_get_default());

  wl_compositor* compositor =
      gdk_wayland_display_get_wl_compositor(gdk_display);

  fl_renderer_wayland_lazy_init_wl(self);
  if (!self->subcompositor) {
    g_error(
        "fl_renderer_wayland_on_window_map: could not bind to "
        "wl_subcompositor");
    return;
  }

  GdkWaylandWindow* window = GDK_WAYLAND_WINDOW(gtk_widget_get_window(widget));
  if (!window) {
    g_error("fl_renderer_wayland_on_window_map: not a Wayland window");
    return;
  }
  wl_surface* toplevel_surface = gdk_wayland_window_get_wl_surface(window);
  if (!toplevel_surface) {
    g_error("fl_renderer_wayland_on_window_map: could not get wl_surface");
    return;
  }

  self->subsurface.subsurface = wl_subcompositor_get_subsurface(
      self->subcompositor, self->subsurface.surface, toplevel_surface);
  if (!self->subsurface.subsurface) {
    g_error("fl_renderer_wayland_on_window_map: could not create subsurface");
    return;
  }

  wl_subsurface_set_desync(self->subsurface.subsurface);
  wl_subsurface_set_position(self->subsurface.subsurface,
                             self->subsurface.geometry.x,
                             self->subsurface.geometry.y);

  // Give the subsurface an empty input region so the main surface gets input.
  wl_region* region = wl_compositor_create_region(compositor);
  wl_surface_set_input_region(self->subsurface.surface, region);
  wl_region_destroy(region);

  wl_surface_commit(self->subsurface.surface);
}

static void fl_renderer_wayland_on_window_unmap(FlRendererWayland* self,
                                                GtkWidget* widget) {
  g_clear_pointer(&self->subsurface.subsurface, wl_subsurface_destroy);
}

// Implements FlRenderer::create_surfaces.
static gboolean fl_renderer_wayland_create_surfaces(FlRenderer* renderer,
                                                    GtkWidget* widget,
                                                    EGLDisplay display,
                                                    EGLConfig config,
                                                    EGLSurface* visible,
                                                    EGLSurface* resource,
                                                    GError** error) {
  FlRendererWayland* self = FL_RENDERER_WAYLAND(renderer);

  if (self->subsurface.surface || self->subsurface.egl_window ||
      self->resource.surface || self->resource.egl_window) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Surfaces already created");
    return FALSE;
  }

  if (!GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Expected Wayland display");
    return FALSE;
  }
  GdkWaylandDisplay* gdk_display =
      GDK_WAYLAND_DISPLAY(gdk_display_get_default());

  wl_compositor* compositor =
      gdk_wayland_display_get_wl_compositor(gdk_display);
  if (!compositor) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "No wl_compositor");
    return FALSE;
  }

  // Make sure size and scale is not <= 0
  self->subsurface.scale = MAX(self->subsurface.scale, 1);
  self->subsurface.geometry.width = MAX(self->subsurface.geometry.width, 1);
  self->subsurface.geometry.height = MAX(self->subsurface.geometry.height, 1);

  self->subsurface.surface = wl_compositor_create_surface(compositor);
  self->resource.surface = wl_compositor_create_surface(compositor);
  if (!self->subsurface.surface || !self->resource.surface) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Failed to create wl_surfaces");
    return FALSE;
  }
  wl_surface_set_buffer_scale(self->subsurface.surface, self->subsurface.scale);

  gint window_width = self->subsurface.geometry.width * self->subsurface.scale;
  gint window_height =
      self->subsurface.geometry.height * self->subsurface.scale;
  self->subsurface.egl_window = wl_egl_window_create(
      self->subsurface.surface, window_width, window_height);
  self->resource.egl_window =
      wl_egl_window_create(self->resource.surface, 1, 1);
  if (!self->subsurface.egl_window || !self->resource.egl_window) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Failed to create EGL windows");
    return FALSE;
  }

  *visible = eglCreateWindowSurface(display, config,
                                    self->subsurface.egl_window, nullptr);
  *resource = eglCreateWindowSurface(display, config, self->resource.egl_window,
                                     nullptr);
  if (*visible == EGL_NO_SURFACE || *resource == EGL_NO_SURFACE) {
    EGLint egl_error = eglGetError();  // must be before egl_config_to_string()
    g_autofree gchar* config_string = egl_config_to_string(display, config);
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Failed to create EGL surfaces using configuration (%s): %s",
                config_string, egl_error_to_string(egl_error));
    return FALSE;
  }

  GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
  if (!toplevel) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Renderer does not have a widget");
    return FALSE;
  }
  g_signal_connect_object(toplevel, "map",
                          G_CALLBACK(fl_renderer_wayland_on_window_map), self,
                          G_CONNECT_SWAPPED);
  g_signal_connect_object(toplevel, "unmap",
                          G_CALLBACK(fl_renderer_wayland_on_window_unmap), self,
                          G_CONNECT_SWAPPED);
  if (gtk_widget_get_mapped(toplevel)) {
    fl_renderer_wayland_on_window_map(self, toplevel);
  }

  return TRUE;
}

// Implements FlRenderer::set_geometry.
static void fl_renderer_wayland_set_geometry(FlRenderer* renderer,
                                             GdkRectangle* geometry,
                                             gint scale) {
  FlRendererWayland* self = FL_RENDERER_WAYLAND(renderer);

  if (scale != self->subsurface.scale && self->subsurface.surface) {
    wl_surface_set_buffer_scale(self->subsurface.surface, scale);
  }

  // NOTE: position is unscaled but size is scaled.

  if ((geometry->x != self->subsurface.geometry.x ||
       geometry->y != self->subsurface.geometry.y) &&
      self->subsurface.subsurface) {
    wl_subsurface_set_position(self->subsurface.subsurface, geometry->x,
                               geometry->y);
  }

  if ((geometry->width != self->subsurface.geometry.width ||
       geometry->height != self->subsurface.geometry.height ||
       scale != self->subsurface.scale) &&
      self->subsurface.egl_window) {
    wl_egl_window_resize(self->subsurface.egl_window, geometry->width * scale,
                         geometry->height * scale, 0, 0);
  }

  self->subsurface.geometry = *geometry;
  self->subsurface.scale = scale;
}

static void fl_renderer_wayland_class_init(FlRendererWaylandClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_renderer_wayland_dispose;
  FL_RENDERER_CLASS(klass)->create_display = fl_renderer_wayland_create_display;
  FL_RENDERER_CLASS(klass)->create_surfaces =
      fl_renderer_wayland_create_surfaces;
  FL_RENDERER_CLASS(klass)->set_geometry = fl_renderer_wayland_set_geometry;
}

static void fl_renderer_wayland_init(FlRendererWayland* self) {}

FlRendererWayland* fl_renderer_wayland_new() {
  return FL_RENDERER_WAYLAND(
      g_object_new(fl_renderer_wayland_get_type(), nullptr));
}
<commit_msg>Add missing cstring header (fixes fl_renderer_wayland.cc) (#21217)<commit_after>// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#define WL_EGL_PLATFORM

#include "fl_renderer_wayland.h"
#include "flutter/shell/platform/linux/egl_utils.h"

#include <gdk/gdkwayland.h>
#include <wayland-egl-core.h>
#include <cstring>

struct _FlRendererWayland {
  FlRenderer parent_instance;
  wl_registry* registry;
  wl_subcompositor* subcompositor;

  struct {
    wl_subsurface* subsurface;
    wl_surface* surface;
    wl_egl_window* egl_window;
    GdkRectangle geometry;
    gint scale;
  } subsurface;

  // The resource surface will not be mapped, but needs to be a wl_surface
  // because ONLY window EGL surfaces are supported on Wayland.
  struct {
    wl_surface* surface;
    wl_egl_window* egl_window;
  } resource;
};

G_DEFINE_TYPE(FlRendererWayland, fl_renderer_wayland, fl_renderer_get_type())

// wl_registry.global callback.
static void registry_handle_global(void* data,
                                   wl_registry* registry,
                                   uint32_t id,
                                   const char* name,
                                   uint32_t max_version) {
  FlRendererWayland* self = FL_RENDERER_WAYLAND(data);
  if (strcmp(name, wl_subcompositor_interface.name) == 0) {
    uint32_t version = MIN(
        static_cast<uint32_t>(wl_subcompositor_interface.version), max_version);
    self->subcompositor = static_cast<wl_subcompositor*>(
        wl_registry_bind(registry, id, &wl_subcompositor_interface, version));
  }
}

// wl_registry.global_remove callback.
// Can be safely ignored unless we bind to globals that might be removed.
static void registry_handle_global_remove(void*, wl_registry*, uint32_t) {}

static const wl_registry_listener registry_listener = {
    .global = registry_handle_global,
    .global_remove = registry_handle_global_remove,
};

// The first time this function is called, all Wayland globals are initialized
// (which blocks for a round trip to the Wayland compositor).
// Subsequent calls return immediately.
static void fl_renderer_wayland_lazy_init_wl(FlRendererWayland* self) {
  if (self->registry) {
    return;
  }

  GdkWaylandDisplay* gdk_display =
      GDK_WAYLAND_DISPLAY(gdk_display_get_default());
  g_return_if_fail(gdk_display);

  wl_display* display = gdk_wayland_display_get_wl_display(gdk_display);
  self->registry = wl_display_get_registry(display);
  wl_registry_add_listener(self->registry, &registry_listener, self);
  wl_display_roundtrip(display);
}

// Implements GObject::dispose.
static void fl_renderer_wayland_dispose(GObject* object) {
  FlRendererWayland* self = FL_RENDERER_WAYLAND(object);

  g_clear_pointer(&self->registry, wl_registry_destroy);
  g_clear_pointer(&self->subcompositor, wl_subcompositor_destroy);

  g_clear_pointer(&self->subsurface.subsurface, wl_subsurface_destroy);
  g_clear_pointer(&self->subsurface.egl_window, wl_egl_window_destroy);
  g_clear_pointer(&self->subsurface.surface, wl_surface_destroy);

  g_clear_pointer(&self->resource.egl_window, wl_egl_window_destroy);
  g_clear_pointer(&self->resource.surface, wl_surface_destroy);

  G_OBJECT_CLASS(fl_renderer_wayland_parent_class)->dispose(object);
}

// Implements FlRenderer::create_display.
static EGLDisplay fl_renderer_wayland_create_display(FlRenderer* /*renderer*/) {
  GdkWaylandDisplay* gdk_display =
      GDK_WAYLAND_DISPLAY(gdk_display_get_default());
  g_return_val_if_fail(gdk_display, nullptr);
  return eglGetDisplay(gdk_wayland_display_get_wl_display(gdk_display));
}

static void fl_renderer_wayland_on_window_map(FlRendererWayland* self,
                                              GtkWidget* widget) {
  if (self->subsurface.subsurface) {
    g_error("fl_renderer_wayland_on_window_map: already has a subsurface");
    return;
  }

  GdkWaylandDisplay* gdk_display =
      GDK_WAYLAND_DISPLAY(gdk_display_get_default());

  wl_compositor* compositor =
      gdk_wayland_display_get_wl_compositor(gdk_display);

  fl_renderer_wayland_lazy_init_wl(self);
  if (!self->subcompositor) {
    g_error(
        "fl_renderer_wayland_on_window_map: could not bind to "
        "wl_subcompositor");
    return;
  }

  GdkWaylandWindow* window = GDK_WAYLAND_WINDOW(gtk_widget_get_window(widget));
  if (!window) {
    g_error("fl_renderer_wayland_on_window_map: not a Wayland window");
    return;
  }
  wl_surface* toplevel_surface = gdk_wayland_window_get_wl_surface(window);
  if (!toplevel_surface) {
    g_error("fl_renderer_wayland_on_window_map: could not get wl_surface");
    return;
  }

  self->subsurface.subsurface = wl_subcompositor_get_subsurface(
      self->subcompositor, self->subsurface.surface, toplevel_surface);
  if (!self->subsurface.subsurface) {
    g_error("fl_renderer_wayland_on_window_map: could not create subsurface");
    return;
  }

  wl_subsurface_set_desync(self->subsurface.subsurface);
  wl_subsurface_set_position(self->subsurface.subsurface,
                             self->subsurface.geometry.x,
                             self->subsurface.geometry.y);

  // Give the subsurface an empty input region so the main surface gets input.
  wl_region* region = wl_compositor_create_region(compositor);
  wl_surface_set_input_region(self->subsurface.surface, region);
  wl_region_destroy(region);

  wl_surface_commit(self->subsurface.surface);
}

static void fl_renderer_wayland_on_window_unmap(FlRendererWayland* self,
                                                GtkWidget* widget) {
  g_clear_pointer(&self->subsurface.subsurface, wl_subsurface_destroy);
}

// Implements FlRenderer::create_surfaces.
static gboolean fl_renderer_wayland_create_surfaces(FlRenderer* renderer,
                                                    GtkWidget* widget,
                                                    EGLDisplay display,
                                                    EGLConfig config,
                                                    EGLSurface* visible,
                                                    EGLSurface* resource,
                                                    GError** error) {
  FlRendererWayland* self = FL_RENDERER_WAYLAND(renderer);

  if (self->subsurface.surface || self->subsurface.egl_window ||
      self->resource.surface || self->resource.egl_window) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Surfaces already created");
    return FALSE;
  }

  if (!GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Expected Wayland display");
    return FALSE;
  }
  GdkWaylandDisplay* gdk_display =
      GDK_WAYLAND_DISPLAY(gdk_display_get_default());

  wl_compositor* compositor =
      gdk_wayland_display_get_wl_compositor(gdk_display);
  if (!compositor) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "No wl_compositor");
    return FALSE;
  }

  // Make sure size and scale is not <= 0
  self->subsurface.scale = MAX(self->subsurface.scale, 1);
  self->subsurface.geometry.width = MAX(self->subsurface.geometry.width, 1);
  self->subsurface.geometry.height = MAX(self->subsurface.geometry.height, 1);

  self->subsurface.surface = wl_compositor_create_surface(compositor);
  self->resource.surface = wl_compositor_create_surface(compositor);
  if (!self->subsurface.surface || !self->resource.surface) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Failed to create wl_surfaces");
    return FALSE;
  }
  wl_surface_set_buffer_scale(self->subsurface.surface, self->subsurface.scale);

  gint window_width = self->subsurface.geometry.width * self->subsurface.scale;
  gint window_height =
      self->subsurface.geometry.height * self->subsurface.scale;
  self->subsurface.egl_window = wl_egl_window_create(
      self->subsurface.surface, window_width, window_height);
  self->resource.egl_window =
      wl_egl_window_create(self->resource.surface, 1, 1);
  if (!self->subsurface.egl_window || !self->resource.egl_window) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Failed to create EGL windows");
    return FALSE;
  }

  *visible = eglCreateWindowSurface(display, config,
                                    self->subsurface.egl_window, nullptr);
  *resource = eglCreateWindowSurface(display, config, self->resource.egl_window,
                                     nullptr);
  if (*visible == EGL_NO_SURFACE || *resource == EGL_NO_SURFACE) {
    EGLint egl_error = eglGetError();  // must be before egl_config_to_string()
    g_autofree gchar* config_string = egl_config_to_string(display, config);
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Failed to create EGL surfaces using configuration (%s): %s",
                config_string, egl_error_to_string(egl_error));
    return FALSE;
  }

  GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
  if (!toplevel) {
    g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
                "Renderer does not have a widget");
    return FALSE;
  }
  g_signal_connect_object(toplevel, "map",
                          G_CALLBACK(fl_renderer_wayland_on_window_map), self,
                          G_CONNECT_SWAPPED);
  g_signal_connect_object(toplevel, "unmap",
                          G_CALLBACK(fl_renderer_wayland_on_window_unmap), self,
                          G_CONNECT_SWAPPED);
  if (gtk_widget_get_mapped(toplevel)) {
    fl_renderer_wayland_on_window_map(self, toplevel);
  }

  return TRUE;
}

// Implements FlRenderer::set_geometry.
static void fl_renderer_wayland_set_geometry(FlRenderer* renderer,
                                             GdkRectangle* geometry,
                                             gint scale) {
  FlRendererWayland* self = FL_RENDERER_WAYLAND(renderer);

  if (scale != self->subsurface.scale && self->subsurface.surface) {
    wl_surface_set_buffer_scale(self->subsurface.surface, scale);
  }

  // NOTE: position is unscaled but size is scaled.

  if ((geometry->x != self->subsurface.geometry.x ||
       geometry->y != self->subsurface.geometry.y) &&
      self->subsurface.subsurface) {
    wl_subsurface_set_position(self->subsurface.subsurface, geometry->x,
                               geometry->y);
  }

  if ((geometry->width != self->subsurface.geometry.width ||
       geometry->height != self->subsurface.geometry.height ||
       scale != self->subsurface.scale) &&
      self->subsurface.egl_window) {
    wl_egl_window_resize(self->subsurface.egl_window, geometry->width * scale,
                         geometry->height * scale, 0, 0);
  }

  self->subsurface.geometry = *geometry;
  self->subsurface.scale = scale;
}

static void fl_renderer_wayland_class_init(FlRendererWaylandClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_renderer_wayland_dispose;
  FL_RENDERER_CLASS(klass)->create_display = fl_renderer_wayland_create_display;
  FL_RENDERER_CLASS(klass)->create_surfaces =
      fl_renderer_wayland_create_surfaces;
  FL_RENDERER_CLASS(klass)->set_geometry = fl_renderer_wayland_set_geometry;
}

static void fl_renderer_wayland_init(FlRendererWayland* self) {}

FlRendererWayland* fl_renderer_wayland_new() {
  return FL_RENDERER_WAYLAND(
      g_object_new(fl_renderer_wayland_get_type(), nullptr));
}
<|endoftext|>


<commit_before>#ifndef PCL_MODEL_HPP_
#define PCL_MODEL_HPP_

#include <GL/gl.h>
#include <GL/glu.h>

#include <boost/shared_ptr.hpp>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
//RWX support disabled due to libbot depencency
//#include <bot_vis/bot_vis.h>

// Polygons:
#include <pcl/io/vtk_lib_io.h>

namespace pcl
{

typedef struct _SinglePoly {
  float* vertices_;
  float* colors_;
  GLenum mode_;
  size_t nvertices_;
} SinglePoly;

class Model
{
public:
  virtual void draw() = 0;

  typedef boost::shared_ptr<Model> Ptr;
  typedef boost::shared_ptr<const Model> ConstPtr;
};

/*
 * RWX support disabled due to libbot depencency

class RWXModel : public Model
{
public:
  RWXModel(const std::string & filename);
  virtual ~RWXModel();
  virtual void draw();

  typedef boost::shared_ptr<RWXModel> Ptr;
  typedef boost::shared_ptr<const RWXModel> ConstPtr;
private:
  std::string filename_;
  BotRwxModel* rwx_model_;
  bool display_list_ready_;
  GLuint rwx_dl_;
};
*/

class PolygonMeshModel : public Model
{
public:
  PolygonMeshModel(GLenum mode, pcl::PolygonMesh::Ptr plg);
  virtual ~PolygonMeshModel();
  virtual void draw();

  typedef boost::shared_ptr<PolygonMeshModel> Ptr;
  typedef boost::shared_ptr<const PolygonMeshModel> ConstPtr;
private:
  std::vector<SinglePoly> polygons;

  /*
    GL_POINTS;
    GL_LINE_STRIP;
    GL_LINE_LOOP;
    GL_LINES;
    GL_TRIANGLE_STRIP;
    GL_TRIANGLE_FAN;
    GL_TRIANGLES;
    GL_QUAD_STRIP;
    GL_QUADS;
    GL_POLYGON;
  */
  GLenum mode_;
};

class PointCloudModel : public Model
{
public:
  PointCloudModel(GLenum mode, pcl::PointCloud<pcl::PointXYZRGBA>::Ptr pc);
  virtual ~PointCloudModel();
  virtual void draw();

  typedef boost::shared_ptr<PointCloudModel> Ptr;
  typedef boost::shared_ptr<const PointCloudModel> ConstPtr;
private:
  float* vertices_;
  float* colors_;

  /*
    GL_POINTS;
    GL_LINE_STRIP;
    GL_LINE_LOOP;
    GL_LINES;
    GL_TRIANGLE_STRIP;
    GL_TRIANGLE_FAN;
    GL_TRIANGLES;
    GL_QUAD_STRIP;
    GL_QUADS;
    GL_POLYGON;
  */
  GLenum mode_;
  size_t nvertices_;
};

}

#endif /* PCL_MODEL_HPP_ */
<commit_msg>#include <windows.h> before #including gl.h<commit_after>#ifndef PCL_MODEL_HPP_
#define PCL_MODEL_HPP_

#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__)
# define WIN32_LEAN_AND_MEAN 1
# include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>

#include <boost/shared_ptr.hpp>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
//RWX support disabled due to libbot depencency
//#include <bot_vis/bot_vis.h>

// Polygons:
#include <pcl/io/vtk_lib_io.h>

namespace pcl
{

typedef struct _SinglePoly {
  float* vertices_;
  float* colors_;
  GLenum mode_;
  size_t nvertices_;
} SinglePoly;

class Model
{
public:
  virtual void draw() = 0;

  typedef boost::shared_ptr<Model> Ptr;
  typedef boost::shared_ptr<const Model> ConstPtr;
};

/*
 * RWX support disabled due to libbot depencency

class RWXModel : public Model
{
public:
  RWXModel(const std::string & filename);
  virtual ~RWXModel();
  virtual void draw();

  typedef boost::shared_ptr<RWXModel> Ptr;
  typedef boost::shared_ptr<const RWXModel> ConstPtr;
private:
  std::string filename_;
  BotRwxModel* rwx_model_;
  bool display_list_ready_;
  GLuint rwx_dl_;
};
*/

class PolygonMeshModel : public Model
{
public:
  PolygonMeshModel(GLenum mode, pcl::PolygonMesh::Ptr plg);
  virtual ~PolygonMeshModel();
  virtual void draw();

  typedef boost::shared_ptr<PolygonMeshModel> Ptr;
  typedef boost::shared_ptr<const PolygonMeshModel> ConstPtr;
private:
  std::vector<SinglePoly> polygons;

  /*
    GL_POINTS;
    GL_LINE_STRIP;
    GL_LINE_LOOP;
    GL_LINES;
    GL_TRIANGLE_STRIP;
    GL_TRIANGLE_FAN;
    GL_TRIANGLES;
    GL_QUAD_STRIP;
    GL_QUADS;
    GL_POLYGON;
  */
  GLenum mode_;
};

class PointCloudModel : public Model
{
public:
  PointCloudModel(GLenum mode, pcl::PointCloud<pcl::PointXYZRGBA>::Ptr pc);
  virtual ~PointCloudModel();
  virtual void draw();

  typedef boost::shared_ptr<PointCloudModel> Ptr;
  typedef boost::shared_ptr<const PointCloudModel> ConstPtr;
private:
  float* vertices_;
  float* colors_;

  /*
    GL_POINTS;
    GL_LINE_STRIP;
    GL_LINE_LOOP;
    GL_LINES;
    GL_TRIANGLE_STRIP;
    GL_TRIANGLE_FAN;
    GL_TRIANGLES;
    GL_QUAD_STRIP;
    GL_QUADS;
    GL_POLYGON;
  */
  GLenum mode_;
  size_t nvertices_;
};

}

#endif /* PCL_MODEL_HPP_ */
<|endoftext|>


<commit_before>

AliAnalysisTask *AddTaskCombinedHadronSpectra(Int_t identifier = 0, Bool_t isMC = kFALSE, Bool_t isTPConly = kFALSE, Bool_t writeOwnFile = kFALSE, Bool_t saveMotherPDG = kFALSE, Bool_t smallTHnSparse = kFALSE, Double_t nSigmaTPCLow= -3., Double_t nSigmaTPCHigh = 3., Double_t rapidityLow = -0.2, Double_t rapidityHigh = 0.2, Bool_t setTrackCuts = kFALSE, AliESDtrackCuts *ESDtrackCuts = 0){

  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_janielsk_CombinedHadron", "No analysis manager found.");
    return 0;
  }
  //============= Set Task Name ===================
  TString taskName=("AliAnalysisCombinedHadronSpectra.cxx+g");
  //===============================================
  //            Load the task
  gROOT->LoadMacro(taskName.Data());

  //========= Add task to the ANALYSIS manager =====

  //normal tracks
  AliAnalysisCombinedHadronSpectra *task = new AliAnalysisCombinedHadronSpectra("janielskTaskCombinedHadron");
  task->SelectCollisionCandidates(AliVEvent::kMB);

  //switches
  if (isMC) task->SetIsMCtrue(isMC);
  if (isTPConly)task->SetUseTPConlyTracks(isTPConly);
  if (saveMotherPDG) task->SetSaveMotherPDG(saveMotherPDG);
  if (smallTHnSparse){
    task->SetSmallTHnSparse(kTRUE);
    task->SetTPCnSigmaCuts(-3.,3.);
    task->SetRapidityCuts(-0.2,0.2);
  }

  //initialize task
  task->Initialize();

  //esd cuts need to be set after initialize or cuts will be replaced by standard cuts in initialize
  if (setTrackCuts) task->SetESDtrackCuts(ESDtrackCuts);

  //add task to manager
  mgr->AddTask(task);

  //================================================
  //              data containers
  //================================================
  //            find input container
  //below the trunk version
  AliAnalysisDataContainer *cinput  = mgr->GetCommonInputContainer();

/*
  //dumm output container
  AliAnalysisDataContainer *coutput0 =
      mgr->CreateContainer(Form("akalweit_tree%i",identifier),
                           TTree::Class(),
                           AliAnalysisManager::kExchangeContainer,
                           Form("akalweit_default%i",identifier));

  //define output containers, please use 'username'_'somename'
  AliAnalysisDataContainer *coutput1 =
      mgr->CreateContainer(Form("akalweit_CombinedHadron%i",identifier), TList::Class(),
                           AliAnalysisManager::kOutputContainer,Form("akalweit_CombinedHadron%i.root",identifier));
*/
  if (!writeOwnFile) {
  	AliAnalysisDataContainer *coutput1 =  mgr->CreateContainer(Form("janielsk_CombinedHadron%i",identifier), TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:janielsk_CombinedHadron", AliAnalysisManager::GetCommonFileName()));
	}
  else {
	AliAnalysisDataContainer *coutput1 =  mgr->CreateContainer(Form("janielsk_CombinedHadron%i",identifier), TList::Class(), AliAnalysisManager::kOutputContainer, Form("janielsk_CombinedHadron.root"));
	}

  //connect containers

  //
  mgr->ConnectInput  (task,  0, cinput );
  //mgr->ConnectOutput (task,  0, coutput0);
  mgr->ConnectOutput (task,  1, coutput1);

  return task;
}
<commit_msg>Fixed bug in AddTask macro<commit_after>

AliAnalysisTask *AddTaskCombinedHadronSpectra(Int_t identifier = 0, Bool_t isMC = kFALSE, Bool_t isTPConly = kFALSE, Bool_t writeOwnFile = kFALSE, Bool_t saveMotherPDG = kFALSE, Bool_t smallTHnSparse = kFALSE, Double_t nSigmaTPCLow= -3., Double_t nSigmaTPCHigh = 3., Double_t rapidityLow = -0.2, Double_t rapidityHigh = 0.2, Bool_t setTrackCuts = kFALSE, AliESDtrackCuts *ESDtrackCuts = 0){

  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_janielsk_CombinedHadron", "No analysis manager found.");
    return 0;
  }
  //============= Set Task Name ===================
  TString taskName=("AliAnalysisCombinedHadronSpectra.cxx+g");
  //===============================================
  //            Load the task
  gROOT->LoadMacro(taskName.Data());

  //========= Add task to the ANALYSIS manager =====

  //normal tracks
  AliAnalysisCombinedHadronSpectra *task = new AliAnalysisCombinedHadronSpectra("janielskTaskCombinedHadron");
  task->SelectCollisionCandidates(AliVEvent::kMB);

  //switches
  if (isMC) task->SetIsMCtrue(isMC);
  if (isTPConly)task->SetUseTPConlyTracks(isTPConly);
  if (saveMotherPDG) task->SetSaveMotherPDG(saveMotherPDG);
  if (smallTHnSparse){
    task->SetSmallTHnSparse(kTRUE);
    task->SetTPCnSigmaCuts(nSigmaTPCLow,nSigmaTPCHigh);
    task->SetRapidityCuts(rapidityLow,rapidityHigh);
  }

  //initialize task
  task->Initialize();

  //esd cuts need to be set after initialize or cuts will be replaced by standard cuts in initialize
  if (setTrackCuts) task->SetESDtrackCuts(ESDtrackCuts);

  //add task to manager
  mgr->AddTask(task);

  //================================================
  //              data containers
  //================================================
  //            find input container
  //below the trunk version
  AliAnalysisDataContainer *cinput  = mgr->GetCommonInputContainer();

/*
  //dumm output container
  AliAnalysisDataContainer *coutput0 =
      mgr->CreateContainer(Form("akalweit_tree%i",identifier),
                           TTree::Class(),
                           AliAnalysisManager::kExchangeContainer,
                           Form("akalweit_default%i",identifier));

  //define output containers, please use 'username'_'somename'
  AliAnalysisDataContainer *coutput1 =
      mgr->CreateContainer(Form("akalweit_CombinedHadron%i",identifier), TList::Class(),
                           AliAnalysisManager::kOutputContainer,Form("akalweit_CombinedHadron%i.root",identifier));
*/
  if (!writeOwnFile) {
  	AliAnalysisDataContainer *coutput1 =  mgr->CreateContainer(Form("janielsk_CombinedHadron%i",identifier), TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:janielsk_CombinedHadron", AliAnalysisManager::GetCommonFileName()));
	}
  else {
	AliAnalysisDataContainer *coutput1 =  mgr->CreateContainer(Form("janielsk_CombinedHadron%i",identifier), TList::Class(), AliAnalysisManager::kOutputContainer, Form("janielsk_CombinedHadron.root"));
	}

  //connect containers

  //
  mgr->ConnectInput  (task,  0, cinput );
  //mgr->ConnectOutput (task,  0, coutput0);
  mgr->ConnectOutput (task,  1, coutput1);

  return task;
}
<|endoftext|>


<commit_before><commit_msg>* Fix for previous commit.<commit_after><|endoftext|>


<commit_before>//!
//! @file   FileAccess.cc
//! @author Robert Braun <robert.braun@liu.se>
//! @date   2010-02-03
//!
//! @brief Contains the file access functions
//!
//$Id$

#include "FileAccess.h"
#include "Component.h"
#include <iostream>
#include <cassert>
#include "HopsanCore.h"

FileAccess::FileAccess()
{
    //Nothing
}

FileAccess::FileAccess(string filename)
{
    mFilename = filename;
}

void FileAccess::setFilename(string filename)
{
    mFilename = filename;
}

ComponentSystem FileAccess::loadModel(double *startTime, double *stopTime, string *plotComponent, string *plotPort)
{
        //Read from file
    ifstream modelFile (mFilename.c_str());
    if(!modelFile.is_open())
    {
        cout <<"Model file does not exist!\n";
        assert(false);
        //TODO: Cast an exception
    }

        //Necessary declarations
    HopsanEssentials Hopsan;
    ComponentSystem mainModel("mainModel");
    typedef map<string, Component*> mapComponentType;
    typedef map<string, ComponentSystem*> mapSystemType;
	mapComponentType componentMap;
	mapSystemType componentSystemMap;
    string inputLine;
    string inputWord;

    while (! modelFile.eof() )
    {
            //Read the line
        getline(modelFile,inputLine);                                   //Read a line
        stringstream inputStream(inputLine);

            //Extract first word unless stream is empty
        if ( inputStream >> inputWord )
        {

            //----------- Create New SubSystem -----------//

            if ( inputWord == "SUBSYSTEM" )
            {
                ComponentSystem *tempComponentSystem = new ComponentSystem();
                inputStream >> inputWord;
                tempComponentSystem->setName(inputWord);
                componentSystemMap.insert(pair<string, ComponentSystem*>(inputWord, &*tempComponentSystem));
                inputStream >> inputWord;
                tempComponentSystem->setTypeCQS(inputWord);
                if ( inputStream >> inputWord )
                {
                    componentSystemMap.find(inputWord)->second->addComponent(tempComponentSystem);      //Subsystem belongs to other subsystem
                }
                else
                {
                    mainModel.addComponent(tempComponentSystem);                 //Subsystem belongs to main system
                }
            }

            //----------- Add Port To SubSystem -----------//

            else if ( inputWord == "SYSTEMPORT")
            {
                string subSystemName, portName;
                //Component* getComponent(string name);
                inputStream >> subSystemName;
                inputStream >> portName;
                componentSystemMap.find(subSystemName)->second->addSystemPort(portName);
            }

            //----------- Create New Component -----------//

            else if ( inputWord == "COMPONENT" )
            {
                inputStream >> inputWord;
                Component *tempComponent = Hopsan.CreateComponent(inputWord);
                inputStream >> inputWord;
                tempComponent->setName(inputWord);
                componentMap.insert(pair<string, Component*>(inputWord, &*tempComponent));
                if ( inputStream >> inputWord )
                {
                    componentSystemMap.find(inputWord)->second->addComponent(tempComponent);      //Componenet belongs to subsystem
                }
                else
                {
                    mainModel.addComponent(tempComponent);                 //Component belongs to main system
                }
            }

            //----------- Connect Components -----------//

            else if ( inputWord == "CONNECT" )
            {
                string firstComponent, firstPort, secondComponent, secondPort;
                inputStream >> firstComponent;
                inputStream >> firstPort;
                inputStream >> secondComponent;
                inputStream >> secondPort;

                if ( componentMap.count(firstComponent) > 0 && componentMap.count(secondComponent) > 0 )        //Connecting two components
                {
                    componentMap.find(firstComponent)->second->getSystemparent().connect(*componentMap.find(firstComponent)->second, firstPort, *componentMap.find(secondComponent)->second, secondPort);
                }
                else if ( componentMap.count(firstComponent) > 0 && componentSystemMap.count(secondComponent) > 0 )     //Connecting component with subsystem
                {
                    componentMap.find(firstComponent)->second->getSystemparent().connect(*componentMap.find(firstComponent)->second, firstPort, *componentSystemMap.find(secondComponent)->second, secondPort);
                }
                else if ( componentSystemMap.count(firstComponent) > 0 && componentMap.count(secondComponent) > 0 )     //Connecting subsystem with component
                {
                   componentMap.find(secondComponent)->second->getSystemparent().connect(*componentSystemMap.find(firstComponent)->second, firstPort, *componentMap.find(secondComponent)->second, secondPort);
                }
                else  //Connecting subsystem with subsystem
                {
                     componentMap.find(firstComponent)->second->getSystemparent().connect(*componentSystemMap.find(firstComponent)->second, firstPort, *componentSystemMap.find(secondComponent)->second, secondPort);
                }
            }
                //Execute commands
            //----------- Set Parameter Value -----------//

            else if ( inputWord == "SET" )
            {
                string componentName, parameterName;
                double parameterValue;
                inputStream >> componentName;
                inputStream >> parameterName;
                inputStream >> parameterValue;
                componentMap.find(componentName)->second->setParameter(parameterName, parameterValue);
            }

            //----------- Set Simulation Parameters -----------//

            else if ( inputWord == "SIMULATE" )
            {
                double temp;
                inputStream >> temp;
                *startTime = temp;
                inputStream >> temp;
                *stopTime = temp;
            }

            //----------- Select Plotting Parameters -----------//

            else if ( inputWord == "PLOT" )
            {
                inputStream >> *plotComponent;
                inputStream >> *plotPort;
            }

            //----------- Unrecognized Command -----------//

            else
            {
                cout << "Unidentified command in model file ignored.\n";
            }
        }
        else
        {
            //cout << "Ignoring empty line.\n";
        }

    }
    modelFile.close();

    return mainModel;
}

ComponentSystem FileAccess::loadModel(string filename, double *startTime, double *stopTime, string *plotComponent, string *plotPort)
{
    setFilename(filename);
    return loadModel(&*startTime, &*stopTime, &*plotComponent, &*plotPort);
}

void FileAccess::saveModel(ComponentSystem mainModel)
{
    ofstream modelFile("savedmodel.txt");
    saveComponentSystem(modelFile, mainModel, "");
    modelFile.close();
    return;
}

void FileAccess::saveComponentSystem(ofstream& modelFile, ComponentSystem& motherModel, string motherSystemName)
{
    map<string, string> mainComponentList = motherModel.getComponentNames();
    map<string, string>::iterator it;
    map<Port*, string> portList;

    for(it = mainComponentList.begin(); it!=mainComponentList.end(); ++it)
    {
        if (it->second == "ComponentSystem")
        {
            modelFile << "SUBSYSTEM " << it->second << " " << it->first << "\n";
            ///TODO: Skriv ut subsystemets portar
            ///TODO: Fixa så man kan komma åt subsystem ur ett component system, så rekursiva anrop kan göras här
            //saveComponentSystem(modelFile, motherModel.getComponent(it->second), motherSystemName + " " + it->first);
        }
        else
        {
                //Write the create component line in the file
            modelFile << "COMPONENT " << it->second << " " << it->first << motherSystemName << "\n";
        }

        map<string,double> componentParameterList = motherModel.getComponent(it->first)->getParameterList();
        map<string, double>::iterator itc;
        for(itc = componentParameterList.begin(); itc!=componentParameterList.end(); ++itc)
        {
            modelFile << "SET " << it->first << " " << itc->first << " " << itc->second << "\n";
        }

            //Store all ports in a map, together with the name of the component they belong to (for use below)
        vector <Port*> portPtrsVector = motherModel.getComponent(it->first)->getPortPtrVector();
        vector <Port*>::iterator itp;
        for (itp=portPtrsVector.begin(); itp!=portPtrsVector.end(); ++itp)
        {
            Port* tempPort = *itp;
            portList.insert(pair<Port*,string>(*itp, it->first));
        }
    }

        //Iterate through port map and figure out which ports share the same node, and then write the connect lines
    map<Port*, string>::iterator itp;
    for(itp = portList.begin(); itp != portList.end(); ++itp)
    {
        map<Port*, string>::iterator itp2;
        for(itp2 = portList.begin(); itp2 != portList.end(); ++itp2)
        {
            Node *ptr1 = itp->first->getNodePublic();
            Node *ptr2 = itp2->first->getNodePublic();
            if (ptr1 == ptr2 && itp != itp2)
            {
                modelFile << "CONNECT " << itp->second << " " << itp->first->getPortName() << " " << itp2->second << " " << itp2->first->getPortName() << "\n";
            }
        }
        portList.erase(itp++);          //Increase itp by 1, then remove previous value from map to prevent double connection
    }
}
<commit_msg>Changed to isComponentSystem instead of name comparison<commit_after>//!
//! @file   FileAccess.cc
//! @author Robert Braun <robert.braun@liu.se>
//! @date   2010-02-03
//!
//! @brief Contains the file access functions
//!
//$Id$

#include "FileAccess.h"
#include "Component.h"
#include <iostream>
#include <cassert>
#include "HopsanCore.h"

FileAccess::FileAccess()
{
    //Nothing
}

FileAccess::FileAccess(string filename)
{
    mFilename = filename;
}

void FileAccess::setFilename(string filename)
{
    mFilename = filename;
}

ComponentSystem FileAccess::loadModel(double *startTime, double *stopTime, string *plotComponent, string *plotPort)
{
        //Read from file
    ifstream modelFile (mFilename.c_str());
    if(!modelFile.is_open())
    {
        cout <<"Model file does not exist!\n";
        assert(false);
        //TODO: Cast an exception
    }

        //Necessary declarations
    HopsanEssentials Hopsan;
    ComponentSystem mainModel("mainModel");
    typedef map<string, Component*> mapComponentType;
    typedef map<string, ComponentSystem*> mapSystemType;
	mapComponentType componentMap;
	mapSystemType componentSystemMap;
    string inputLine;
    string inputWord;

    while (! modelFile.eof() )
    {
            //Read the line
        getline(modelFile,inputLine);                                   //Read a line
        stringstream inputStream(inputLine);

            //Extract first word unless stream is empty
        if ( inputStream >> inputWord )
        {

            //----------- Create New SubSystem -----------//

            if ( inputWord == "SUBSYSTEM" )
            {
                ComponentSystem *tempComponentSystem = new ComponentSystem();
                inputStream >> inputWord;
                tempComponentSystem->setName(inputWord);
                componentSystemMap.insert(pair<string, ComponentSystem*>(inputWord, &*tempComponentSystem));
                inputStream >> inputWord;
                tempComponentSystem->setTypeCQS(inputWord);
                if ( inputStream >> inputWord )
                {
                    componentSystemMap.find(inputWord)->second->addComponent(tempComponentSystem);      //Subsystem belongs to other subsystem
                }
                else
                {
                    mainModel.addComponent(tempComponentSystem);                 //Subsystem belongs to main system
                }
            }

            //----------- Add Port To SubSystem -----------//

            else if ( inputWord == "SYSTEMPORT")
            {
                string subSystemName, portName;
                //Component* getComponent(string name);
                inputStream >> subSystemName;
                inputStream >> portName;
                componentSystemMap.find(subSystemName)->second->addSystemPort(portName);
            }

            //----------- Create New Component -----------//

            else if ( inputWord == "COMPONENT" )
            {
                inputStream >> inputWord;
                Component *tempComponent = Hopsan.CreateComponent(inputWord);
                inputStream >> inputWord;
                tempComponent->setName(inputWord);
                componentMap.insert(pair<string, Component*>(inputWord, &*tempComponent));
                if ( inputStream >> inputWord )
                {
                    componentSystemMap.find(inputWord)->second->addComponent(tempComponent);      //Componenet belongs to subsystem
                }
                else
                {
                    mainModel.addComponent(tempComponent);                 //Component belongs to main system
                }
            }

            //----------- Connect Components -----------//

            else if ( inputWord == "CONNECT" )
            {
                string firstComponent, firstPort, secondComponent, secondPort;
                inputStream >> firstComponent;
                inputStream >> firstPort;
                inputStream >> secondComponent;
                inputStream >> secondPort;

                if ( componentMap.count(firstComponent) > 0 && componentMap.count(secondComponent) > 0 )        //Connecting two components
                {
                    componentMap.find(firstComponent)->second->getSystemparent().connect(*componentMap.find(firstComponent)->second, firstPort, *componentMap.find(secondComponent)->second, secondPort);
                }
                else if ( componentMap.count(firstComponent) > 0 && componentSystemMap.count(secondComponent) > 0 )     //Connecting component with subsystem
                {
                    componentMap.find(firstComponent)->second->getSystemparent().connect(*componentMap.find(firstComponent)->second, firstPort, *componentSystemMap.find(secondComponent)->second, secondPort);
                }
                else if ( componentSystemMap.count(firstComponent) > 0 && componentMap.count(secondComponent) > 0 )     //Connecting subsystem with component
                {
                   componentMap.find(secondComponent)->second->getSystemparent().connect(*componentSystemMap.find(firstComponent)->second, firstPort, *componentMap.find(secondComponent)->second, secondPort);
                }
                else  //Connecting subsystem with subsystem
                {
                     componentMap.find(firstComponent)->second->getSystemparent().connect(*componentSystemMap.find(firstComponent)->second, firstPort, *componentSystemMap.find(secondComponent)->second, secondPort);
                }
            }
                //Execute commands
            //----------- Set Parameter Value -----------//

            else if ( inputWord == "SET" )
            {
                string componentName, parameterName;
                double parameterValue;
                inputStream >> componentName;
                inputStream >> parameterName;
                inputStream >> parameterValue;
                componentMap.find(componentName)->second->setParameter(parameterName, parameterValue);
            }

            //----------- Set Simulation Parameters -----------//

            else if ( inputWord == "SIMULATE" )
            {
                double temp;
                inputStream >> temp;
                *startTime = temp;
                inputStream >> temp;
                *stopTime = temp;
            }

            //----------- Select Plotting Parameters -----------//

            else if ( inputWord == "PLOT" )
            {
                inputStream >> *plotComponent;
                inputStream >> *plotPort;
            }

            //----------- Unrecognized Command -----------//

            else
            {
                cout << "Unidentified command in model file ignored.\n";
            }
        }
        else
        {
            //cout << "Ignoring empty line.\n";
        }

    }
    modelFile.close();

    return mainModel;
}

ComponentSystem FileAccess::loadModel(string filename, double *startTime, double *stopTime, string *plotComponent, string *plotPort)
{
    setFilename(filename);
    return loadModel(&*startTime, &*stopTime, &*plotComponent, &*plotPort);
}

void FileAccess::saveModel(ComponentSystem mainModel)
{
    ofstream modelFile("savedmodel.txt");
    saveComponentSystem(modelFile, mainModel, "");
    modelFile.close();
    return;
}

void FileAccess::saveComponentSystem(ofstream& modelFile, ComponentSystem& motherModel, string motherSystemName)
{
    map<string, string> mainComponentList = motherModel.getComponentNames();
    map<string, string>::iterator it;
    map<Port*, string> portList;

    for(it = mainComponentList.begin(); it!=mainComponentList.end(); ++it)
    {
        //if (it->second == "ComponentSystem")
        if(motherModel.getComponent(it->first)->isComponentSystem())
        {
            modelFile << "SUBSYSTEM " << it->second << " " << it->first << "\n";
            ///TODO: Skriv ut subsystemets portar
            ///TODO: Fixa så man kan komma åt subsystem ur ett component system, så rekursiva anrop kan göras här
            //saveComponentSystem(modelFile, motherModel.getComponent(it->second), motherSystemName + " " + it->first);
        }
        else
        {
                //Write the create component line in the file
            modelFile << "COMPONENT " << it->second << " " << it->first << motherSystemName << "\n";
        }

        map<string,double> componentParameterList = motherModel.getComponent(it->first)->getParameterList();
        map<string, double>::iterator itc;
        for(itc = componentParameterList.begin(); itc!=componentParameterList.end(); ++itc)
        {
            modelFile << "SET " << it->first << " " << itc->first << " " << itc->second << "\n";
        }

            //Store all ports in a map, together with the name of the component they belong to (for use below)
        vector <Port*> portPtrsVector = motherModel.getComponent(it->first)->getPortPtrVector();
        vector <Port*>::iterator itp;
        for (itp=portPtrsVector.begin(); itp!=portPtrsVector.end(); ++itp)
        {
            Port* tempPort = *itp;
            portList.insert(pair<Port*,string>(*itp, it->first));
        }
    }

        //Iterate through port map and figure out which ports share the same node, and then write the connect lines
    map<Port*, string>::iterator itp;
    for(itp = portList.begin(); itp != portList.end(); ++itp)
    {
        map<Port*, string>::iterator itp2;
        for(itp2 = portList.begin(); itp2 != portList.end(); ++itp2)
        {
            Node *ptr1 = itp->first->getNodePublic();
            Node *ptr2 = itp2->first->getNodePublic();
            if (ptr1 == ptr2 && itp != itp2)
            {
                modelFile << "CONNECT " << itp->second << " " << itp->first->getPortName() << " " << itp2->second << " " << itp2->first->getPortName() << "\n";
            }
        }
        portList.erase(itp++);          //Increase itp by 1, then remove previous value from map to prevent double connection
    }
}
<|endoftext|>


<commit_before><commit_msg>Add support for RGBA buffer formats in Texture::generatePrefilterMipmap<commit_after><|endoftext|>


<commit_before><commit_msg>UTXX: fixed some comments in convert.hpp<commit_after><|endoftext|>


<commit_before><commit_msg>Correct forward definition.<commit_after><|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cassert>

#include <ui/DisplayInfo.h>

#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>

#include <GLES2/gl2.h>
#include <EGL/eglext.h>

#define BACKLIGHT_LEVEL "205"

using namespace android;

struct FramebufferState {
    sp<SurfaceComposerClient> session;
    sp<IBinder> dtoken;
    DisplayInfo dinfo;
    sp<SurfaceControl> control;

    sp<Surface> s;
    EGLDisplay display;

    EGLint egl_major, egl_minor;
    EGLConfig config;
    EGLSurface surface;
    EGLContext context;
};

extern "C" void framebuffer_set_power(FramebufferState *s, int mode) {
  SurfaceComposerClient::setDisplayPowerMode(s->dtoken, mode);
}

extern "C" FramebufferState* framebuffer_init(
    const char* name, int32_t layer, int alpha,
    int *out_w, int *out_h) {
  status_t status;
  int success;

  FramebufferState *s = new FramebufferState;

  s->session = new SurfaceComposerClient();
  assert(s->session != NULL);

  s->dtoken = SurfaceComposerClient::getBuiltInDisplay(
                ISurfaceComposer::eDisplayIdMain);
  assert(s->dtoken != NULL);

  status = SurfaceComposerClient::getDisplayInfo(s->dtoken, &s->dinfo);
  assert(status == 0);

  //int orientation = 3; // rotate framebuffer 270 degrees
  int orientation = 1; // rotate framebuffer 90 degrees
  if(orientation == 1 || orientation == 3) {
      int temp = s->dinfo.h;
      s->dinfo.h = s->dinfo.w;
      s->dinfo.w = temp;
  }

  printf("dinfo %dx%d\n", s->dinfo.w, s->dinfo.h);

  Rect destRect(s->dinfo.w, s->dinfo.h);
  s->session->setDisplayProjection(s->dtoken, orientation, destRect, destRect);

  s->control = s->session->createSurface(String8(name),
                  s->dinfo.w, s->dinfo.h, PIXEL_FORMAT_RGBX_8888);
  assert(s->control != NULL);

  SurfaceComposerClient::openGlobalTransaction();
  status = s->control->setLayer(layer);
  SurfaceComposerClient::closeGlobalTransaction();
  assert(status == 0);

  s->s = s->control->getSurface();
  assert(s->s != NULL);

  // init opengl and egl
  const EGLint attribs[] = {
    EGL_RED_SIZE,     8,
    EGL_GREEN_SIZE,   8,
    EGL_BLUE_SIZE,    8,
    EGL_ALPHA_SIZE,   alpha ? 8 : 0,
    EGL_DEPTH_SIZE,   0,
    EGL_STENCIL_SIZE, 8,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
    EGL_NONE,
  };

  s->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  assert(s->display != EGL_NO_DISPLAY);

  success = eglInitialize(s->display, &s->egl_major, &s->egl_minor);
  assert(success);

  printf("egl version %d.%d\n", s->egl_major, s->egl_minor);

  EGLint num_configs;
  success = eglChooseConfig(s->display, attribs, &s->config, 1, &num_configs);
  assert(success);

  s->surface = eglCreateWindowSurface(s->display, s->config, s->s.get(), NULL);
  assert(s->surface != EGL_NO_SURFACE);

  const EGLint context_attribs[] = {
    EGL_CONTEXT_CLIENT_VERSION, 3,
    EGL_NONE,
  };
  s->context = eglCreateContext(s->display, s->config, NULL, context_attribs);
  assert(s->context != EGL_NO_CONTEXT);

  EGLint w, h;
  eglQuerySurface(s->display, s->surface, EGL_WIDTH, &w);
  eglQuerySurface(s->display, s->surface, EGL_HEIGHT, &h);
  printf("egl w %d h %d\n", w, h);

  success = eglMakeCurrent(s->display, s->surface, s->surface, s->context);
  assert(success);

  printf("gl version %s\n", glGetString(GL_VERSION));

  set_brightness(BACKLIGHT_LEVEL);

  if (out_w) *out_w = w;
  if (out_h) *out_h = h;

  return s;
}

extern "C" void framebuffer_swap(FramebufferState *s) {
  eglSwapBuffers(s->display, s->surface);
  assert(glGetError() == GL_NO_ERROR);
}

extern "C" bool set_brightness(int brightness) {
  FILE *f = fopen("/sys/class/leds/lcd-backlight/brightness", "wb");
  if (f != NULL) {
    fprintf(f, "%d", brightness);
    fclose(f);
    return true;
  }
  return false;
}
<commit_msg>Move helper function definition to top of file<commit_after>#include <cstdio>
#include <cstdlib>
#include <cassert>

#include <ui/DisplayInfo.h>

#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>

#include <GLES2/gl2.h>
#include <EGL/eglext.h>

#define BACKLIGHT_LEVEL "205"

using namespace android;

struct FramebufferState {
    sp<SurfaceComposerClient> session;
    sp<IBinder> dtoken;
    DisplayInfo dinfo;
    sp<SurfaceControl> control;

    sp<Surface> s;
    EGLDisplay display;

    EGLint egl_major, egl_minor;
    EGLConfig config;
    EGLSurface surface;
    EGLContext context;
};

extern "C" void framebuffer_swap(FramebufferState *s) {
  eglSwapBuffers(s->display, s->surface);
  assert(glGetError() == GL_NO_ERROR);
}

extern "C" bool set_brightness(int brightness) {
  FILE *f = fopen("/sys/class/leds/lcd-backlight/brightness", "wb");
  if (f != NULL) {
    fprintf(f, "%d", brightness);
    fclose(f);
    return true;
  }
  return false;
}

extern "C" void framebuffer_set_power(FramebufferState *s, int mode) {
  SurfaceComposerClient::setDisplayPowerMode(s->dtoken, mode);
}

extern "C" FramebufferState* framebuffer_init(
    const char* name, int32_t layer, int alpha,
    int *out_w, int *out_h) {
  status_t status;
  int success;

  FramebufferState *s = new FramebufferState;

  s->session = new SurfaceComposerClient();
  assert(s->session != NULL);

  s->dtoken = SurfaceComposerClient::getBuiltInDisplay(
                ISurfaceComposer::eDisplayIdMain);
  assert(s->dtoken != NULL);

  status = SurfaceComposerClient::getDisplayInfo(s->dtoken, &s->dinfo);
  assert(status == 0);

  //int orientation = 3; // rotate framebuffer 270 degrees
  int orientation = 1; // rotate framebuffer 90 degrees
  if(orientation == 1 || orientation == 3) {
      int temp = s->dinfo.h;
      s->dinfo.h = s->dinfo.w;
      s->dinfo.w = temp;
  }

  printf("dinfo %dx%d\n", s->dinfo.w, s->dinfo.h);

  Rect destRect(s->dinfo.w, s->dinfo.h);
  s->session->setDisplayProjection(s->dtoken, orientation, destRect, destRect);

  s->control = s->session->createSurface(String8(name),
                  s->dinfo.w, s->dinfo.h, PIXEL_FORMAT_RGBX_8888);
  assert(s->control != NULL);

  SurfaceComposerClient::openGlobalTransaction();
  status = s->control->setLayer(layer);
  SurfaceComposerClient::closeGlobalTransaction();
  assert(status == 0);

  s->s = s->control->getSurface();
  assert(s->s != NULL);

  // init opengl and egl
  const EGLint attribs[] = {
    EGL_RED_SIZE,     8,
    EGL_GREEN_SIZE,   8,
    EGL_BLUE_SIZE,    8,
    EGL_ALPHA_SIZE,   alpha ? 8 : 0,
    EGL_DEPTH_SIZE,   0,
    EGL_STENCIL_SIZE, 8,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
    EGL_NONE,
  };

  s->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  assert(s->display != EGL_NO_DISPLAY);

  success = eglInitialize(s->display, &s->egl_major, &s->egl_minor);
  assert(success);

  printf("egl version %d.%d\n", s->egl_major, s->egl_minor);

  EGLint num_configs;
  success = eglChooseConfig(s->display, attribs, &s->config, 1, &num_configs);
  assert(success);

  s->surface = eglCreateWindowSurface(s->display, s->config, s->s.get(), NULL);
  assert(s->surface != EGL_NO_SURFACE);

  const EGLint context_attribs[] = {
    EGL_CONTEXT_CLIENT_VERSION, 3,
    EGL_NONE,
  };
  s->context = eglCreateContext(s->display, s->config, NULL, context_attribs);
  assert(s->context != EGL_NO_CONTEXT);

  EGLint w, h;
  eglQuerySurface(s->display, s->surface, EGL_WIDTH, &w);
  eglQuerySurface(s->display, s->surface, EGL_HEIGHT, &h);
  printf("egl w %d h %d\n", w, h);

  success = eglMakeCurrent(s->display, s->surface, s->surface, s->context);
  assert(success);

  printf("gl version %s\n", glGetString(GL_VERSION));

  set_brightness(BACKLIGHT_LEVEL);

  if (out_w) *out_w = w;
  if (out_h) *out_h = h;

  return s;
}
<|endoftext|>


<commit_before>// Copyright (c) 2008 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 "net/base/file_input_stream.h"

#include <windows.h>

#include "base/logging.h"
#include "base/message_loop.h"
#include "net/base/net_errors.h"

namespace net {

// Ensure that we can just use our Whence values directly.
COMPILE_ASSERT(FROM_BEGIN == FILE_BEGIN, bad_whence_begin);
COMPILE_ASSERT(FROM_CURRENT == FILE_CURRENT, bad_whence_current);
COMPILE_ASSERT(FROM_END == FILE_END, bad_whence_end);

static void SetOffset(OVERLAPPED* overlapped, const LARGE_INTEGER& offset) {
  overlapped->Offset = offset.LowPart;
  overlapped->OffsetHigh = offset.HighPart;
}

static void IncrementOffset(OVERLAPPED* overlapped, DWORD count) {
  LARGE_INTEGER offset;
  offset.LowPart = overlapped->Offset;
  offset.HighPart = overlapped->OffsetHigh;
  offset.QuadPart += static_cast<LONGLONG>(count);
  SetOffset(overlapped, offset);
}

static int MapErrorCode(DWORD err) {
  switch (err) {
    case ERROR_FILE_NOT_FOUND:
    case ERROR_PATH_NOT_FOUND:
      return ERR_FILE_NOT_FOUND;
    case ERROR_ACCESS_DENIED:
      return ERR_ACCESS_DENIED;
    case ERROR_SUCCESS:
      return OK;
    default:
      LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED";
      return ERR_FAILED;
  }
}

// FileInputStream::AsyncContext ----------------------------------------------

class FileInputStream::AsyncContext : public MessageLoopForIO::Watcher {
 public:
  AsyncContext(FileInputStream* owner)
      : owner_(owner), overlapped_(), callback_(NULL) {
    overlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  }

  ~AsyncContext() {
    if (callback_)
      MessageLoopForIO::current()->WatchObject(overlapped_.hEvent, NULL);
    CloseHandle(overlapped_.hEvent);
  }

  void IOCompletionIsPending(CompletionCallback* callback);

  OVERLAPPED* overlapped() { return &overlapped_; }
  CompletionCallback* callback() const { return callback_; }

 private:
  // MessageLoopForIO::Watcher implementation:
  virtual void OnObjectSignaled(HANDLE object);

  FileInputStream* owner_;
  OVERLAPPED overlapped_;
  CompletionCallback* callback_;
};

void FileInputStream::AsyncContext::IOCompletionIsPending(
    CompletionCallback* callback) {
  DCHECK(!callback_);
  callback_ = callback;

  MessageLoopForIO::current()->WatchObject(overlapped_.hEvent, this);
}

void FileInputStream::AsyncContext::OnObjectSignaled(HANDLE object) {
  DCHECK(overlapped_.hEvent == object);
  DCHECK(callback_);

  MessageLoopForIO::current()->WatchObject(overlapped_.hEvent, NULL);

  HANDLE handle = owner_->handle_;

  int result;

  DWORD bytes_read;
  if (!GetOverlappedResult(handle, &overlapped_, &bytes_read, FALSE)) {
    DWORD err = GetLastError();
    if (err == ERROR_HANDLE_EOF) {
      result = OK;  // Successfully read all data.
    } else {
      result = MapErrorCode(err);
    }
  } else {
    IncrementOffset(&overlapped_, bytes_read);
    result = static_cast<int>(bytes_read);
  }

  CompletionCallback* temp = NULL;
  std::swap(temp, callback_);
  temp->Run(result);
}

// FileInputStream ------------------------------------------------------------

FileInputStream::FileInputStream() : handle_(INVALID_HANDLE_VALUE) {
}

FileInputStream::~FileInputStream() {
  Close();
}

void FileInputStream::Close() {
  if (handle_ != INVALID_HANDLE_VALUE) {
    CloseHandle(handle_);
    handle_ = INVALID_HANDLE_VALUE;
  }
  async_context_.reset();
}

int FileInputStream::Open(const std::wstring& path, bool asynchronous_mode) {
  if (IsOpen()) {
    DLOG(FATAL) << "File is already open!";
    return ERR_UNEXPECTED;
  }

  // Optimize for streaming, not seeking.  If someone does a lot of random
  // access operations, then we should consider revising this.
  DWORD create_file_flags = FILE_FLAG_SEQUENTIAL_SCAN;

  if (asynchronous_mode)
    create_file_flags |= FILE_FLAG_OVERLAPPED;

  handle_ =
      CreateFile(path.c_str(), GENERIC_READ | SYNCHRONIZE,
                 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                 NULL, OPEN_EXISTING, create_file_flags, NULL);
  if (handle_ == INVALID_HANDLE_VALUE) {
    DWORD error = GetLastError();
    LOG(WARNING) << "Failed to open file: " << error;
    return MapErrorCode(error);
  }

  if (asynchronous_mode)
    async_context_.reset(new AsyncContext(this));

  return OK;
}

bool FileInputStream::IsOpen() const {
  return handle_ != INVALID_HANDLE_VALUE;
}

int64 FileInputStream::Seek(Whence whence, int64 offset) {
  if (!IsOpen())
    return ERR_UNEXPECTED;
  DCHECK(!async_context_.get() || !async_context_->callback());

  LARGE_INTEGER distance, result;
  distance.QuadPart = offset;
  DWORD move_method = static_cast<DWORD>(whence);
  if (!SetFilePointerEx(handle_, distance, &result, move_method)) {
    DWORD error = GetLastError();
    LOG(WARNING) << "SetFilePointerEx failed: " << error;
    return MapErrorCode(error);
  }
  if (async_context_.get())
    SetOffset(async_context_->overlapped(), result);
  return result.QuadPart;
}

int64 FileInputStream::Available() {
  if (!IsOpen())
    return ERR_UNEXPECTED;

  int64 cur_pos = Seek(FROM_CURRENT, 0);
  if (cur_pos < 0)
    return cur_pos;

  LARGE_INTEGER file_size;
  if (!GetFileSizeEx(handle_, &file_size)) {
    DWORD error = GetLastError();
    LOG(WARNING) << "GetFileSizeEx failed: " << error;
    return MapErrorCode(error);
  }

  return file_size.QuadPart - cur_pos;
}

int FileInputStream::Read(
    char* buf, int buf_len, CompletionCallback* callback) {
  if (!IsOpen())
    return ERR_UNEXPECTED;

  OVERLAPPED* overlapped = NULL;
  if (async_context_.get()) {
    DCHECK(!async_context_->callback());
    overlapped = async_context_->overlapped();
  }

  int rv;

  DWORD bytes_read;
  if (!ReadFile(handle_, buf, buf_len, &bytes_read, overlapped)) {
    DWORD error = GetLastError();
    if (async_context_.get() && error == ERROR_IO_PENDING) {
      async_context_->IOCompletionIsPending(callback);
      rv = ERR_IO_PENDING;
    } else if (error == ERROR_HANDLE_EOF) {
      rv = 0;  // Report EOF by returning 0 bytes read.
    } else {
      LOG(WARNING) << "ReadFile failed: " << error;
      rv = MapErrorCode(error);
    }
  } else {
    if (overlapped)
      IncrementOffset(overlapped, bytes_read);
    rv = static_cast<int>(bytes_read);
  }
  return rv;
}

}  // namespace net
<commit_msg>Remove WatchObject calls from FileInputStream.<commit_after>// Copyright (c) 2008 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 "net/base/file_input_stream.h"

#include <windows.h>

#include "base/logging.h"
#include "base/message_loop.h"
#include "net/base/net_errors.h"

namespace net {

// Ensure that we can just use our Whence values directly.
COMPILE_ASSERT(FROM_BEGIN == FILE_BEGIN, bad_whence_begin);
COMPILE_ASSERT(FROM_CURRENT == FILE_CURRENT, bad_whence_current);
COMPILE_ASSERT(FROM_END == FILE_END, bad_whence_end);

static void SetOffset(OVERLAPPED* overlapped, const LARGE_INTEGER& offset) {
  overlapped->Offset = offset.LowPart;
  overlapped->OffsetHigh = offset.HighPart;
}

static void IncrementOffset(OVERLAPPED* overlapped, DWORD count) {
  LARGE_INTEGER offset;
  offset.LowPart = overlapped->Offset;
  offset.HighPart = overlapped->OffsetHigh;
  offset.QuadPart += static_cast<LONGLONG>(count);
  SetOffset(overlapped, offset);
}

static int MapErrorCode(DWORD err) {
  switch (err) {
    case ERROR_FILE_NOT_FOUND:
    case ERROR_PATH_NOT_FOUND:
      return ERR_FILE_NOT_FOUND;
    case ERROR_ACCESS_DENIED:
      return ERR_ACCESS_DENIED;
    case ERROR_SUCCESS:
      return OK;
    default:
      LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED";
      return ERR_FAILED;
  }
}

// FileInputStream::AsyncContext ----------------------------------------------

class FileInputStream::AsyncContext : public MessageLoopForIO::IOHandler {
 public:
  AsyncContext(FileInputStream* owner)
      : owner_(owner), overlapped_(), callback_(NULL) {
    overlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  }

  ~AsyncContext() {
    if (callback_)
      MessageLoopForIO::current()->RegisterIOContext(&overlapped_, NULL);
    CloseHandle(overlapped_.hEvent);
  }

  void IOCompletionIsPending(CompletionCallback* callback);

  OVERLAPPED* overlapped() { return &overlapped_; }
  CompletionCallback* callback() const { return callback_; }

 private:
  // MessageLoopForIO::IOHandler implementation:
  virtual void OnIOCompleted(OVERLAPPED* context, DWORD bytes_read,
                             DWORD error);

  FileInputStream* owner_;
  OVERLAPPED overlapped_;
  CompletionCallback* callback_;
};

void FileInputStream::AsyncContext::IOCompletionIsPending(
    CompletionCallback* callback) {
  DCHECK(!callback_);
  callback_ = callback;

  MessageLoopForIO::current()->RegisterIOContext(&overlapped_, this);
}

void FileInputStream::AsyncContext::OnIOCompleted(OVERLAPPED* context,
                                                  DWORD bytes_read,
                                                  DWORD error) {
  DCHECK(&overlapped_ == context);
  DCHECK(callback_);

  MessageLoopForIO::current()->RegisterIOContext(&overlapped_, NULL);

  HANDLE handle = owner_->handle_;

  int result = static_cast<int>(bytes_read);
  if (error && error != ERROR_HANDLE_EOF)
    result = MapErrorCode(error);

  if (bytes_read)
    IncrementOffset(&overlapped_, bytes_read);

  CompletionCallback* temp = NULL;
  std::swap(temp, callback_);
  temp->Run(result);
}

// FileInputStream ------------------------------------------------------------

FileInputStream::FileInputStream() : handle_(INVALID_HANDLE_VALUE) {
}

FileInputStream::~FileInputStream() {
  Close();
}

void FileInputStream::Close() {
  if (handle_ != INVALID_HANDLE_VALUE) {
    CloseHandle(handle_);
    handle_ = INVALID_HANDLE_VALUE;
  }
  async_context_.reset();
}

int FileInputStream::Open(const std::wstring& path, bool asynchronous_mode) {
  if (IsOpen()) {
    DLOG(FATAL) << "File is already open!";
    return ERR_UNEXPECTED;
  }

  // Optimize for streaming, not seeking.  If someone does a lot of random
  // access operations, then we should consider revising this.
  DWORD create_file_flags = FILE_FLAG_SEQUENTIAL_SCAN;

  if (asynchronous_mode)
    create_file_flags |= FILE_FLAG_OVERLAPPED;

  handle_ =
      CreateFile(path.c_str(), GENERIC_READ | SYNCHRONIZE,
                 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                 NULL, OPEN_EXISTING, create_file_flags, NULL);
  if (handle_ == INVALID_HANDLE_VALUE) {
    DWORD error = GetLastError();
    LOG(WARNING) << "Failed to open file: " << error;
    return MapErrorCode(error);
  }

  if (asynchronous_mode) {
    async_context_.reset(new AsyncContext(this));
    MessageLoopForIO::current()->RegisterIOHandler(handle_,
                                                   async_context_.get());
  }

  return OK;
}

bool FileInputStream::IsOpen() const {
  return handle_ != INVALID_HANDLE_VALUE;
}

int64 FileInputStream::Seek(Whence whence, int64 offset) {
  if (!IsOpen())
    return ERR_UNEXPECTED;
  DCHECK(!async_context_.get() || !async_context_->callback());

  LARGE_INTEGER distance, result;
  distance.QuadPart = offset;
  DWORD move_method = static_cast<DWORD>(whence);
  if (!SetFilePointerEx(handle_, distance, &result, move_method)) {
    DWORD error = GetLastError();
    LOG(WARNING) << "SetFilePointerEx failed: " << error;
    return MapErrorCode(error);
  }
  if (async_context_.get())
    SetOffset(async_context_->overlapped(), result);
  return result.QuadPart;
}

int64 FileInputStream::Available() {
  if (!IsOpen())
    return ERR_UNEXPECTED;

  int64 cur_pos = Seek(FROM_CURRENT, 0);
  if (cur_pos < 0)
    return cur_pos;

  LARGE_INTEGER file_size;
  if (!GetFileSizeEx(handle_, &file_size)) {
    DWORD error = GetLastError();
    LOG(WARNING) << "GetFileSizeEx failed: " << error;
    return MapErrorCode(error);
  }

  return file_size.QuadPart - cur_pos;
}

int FileInputStream::Read(
    char* buf, int buf_len, CompletionCallback* callback) {
  if (!IsOpen())
    return ERR_UNEXPECTED;

  OVERLAPPED* overlapped = NULL;
  if (async_context_.get()) {
    DCHECK(!async_context_->callback());
    overlapped = async_context_->overlapped();
  }

  int rv;

  DWORD bytes_read;
  if (!ReadFile(handle_, buf, buf_len, &bytes_read, overlapped)) {
    DWORD error = GetLastError();
    if (async_context_.get() && error == ERROR_IO_PENDING) {
      async_context_->IOCompletionIsPending(callback);
      rv = ERR_IO_PENDING;
    } else if (error == ERROR_HANDLE_EOF) {
      rv = 0;  // Report EOF by returning 0 bytes read.
    } else {
      LOG(WARNING) << "ReadFile failed: " << error;
      rv = MapErrorCode(error);
    }
  } else {
    if (overlapped)
      IncrementOffset(overlapped, bytes_read);
    rv = static_cast<int>(bytes_read);
  }
  return rv;
}

}  // namespace net
<|endoftext|>