<commit_before>/*
 *  Copyright (c) 2016 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "third_party/googletest/src/include/gtest/gtest.h"

#include "./vpx_config.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"

namespace {

#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))

TEST(EncodeAPI, InvalidParams) {
  static const vpx_codec_iface_t *kCodecs[] = {
#if CONFIG_VP8_ENCODER
    &vpx_codec_vp8_cx_algo,
#endif
#if CONFIG_VP9_ENCODER
    &vpx_codec_vp9_cx_algo,
#endif
  };
  uint8_t buf[1] = { 0 };
  vpx_image_t img;
  vpx_codec_ctx_t enc;
  vpx_codec_enc_cfg_t cfg;

  EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf));

  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(NULL, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(&enc, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, NULL, 0, 0, 0, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, &img, 0, 0, 0, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_enc_config_default(NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_enc_config_default(NULL, &cfg, 0));
  EXPECT_TRUE(vpx_codec_error(NULL) != NULL);

  for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
    SCOPED_TRACE(vpx_codec_iface_name(kCodecs[i]));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_init(NULL, kCodecs[i], NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_init(&enc, kCodecs[i], NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_config_default(kCodecs[i], &cfg, 1));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(kCodecs[i], &cfg, 0));
    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, kCodecs[i], &cfg, 0));
    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, NULL, 0, 0, 0, 0));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
  }
}

TEST(EncodeAPI, HighBitDepthCapability) {
// VP8 should not claim VP9 HBD as a capability.
#if CONFIG_VP8_ENCODER
  const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo);
  EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
#endif

#if CONFIG_VP9_ENCODER
  const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo);
#if CONFIG_VP9_HIGHBITDEPTH
  EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
#else
  EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
#endif
#endif
}

}  // namespace
<commit_msg>Add unit test to expose vp8 bug when width is set odd.<commit_after>/*
 *  Copyright (c) 2016 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "third_party/googletest/src/include/gtest/gtest.h"

#include "./vpx_config.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"

namespace {

#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))

TEST(EncodeAPI, InvalidParams) {
  static const vpx_codec_iface_t *kCodecs[] = {
#if CONFIG_VP8_ENCODER
    &vpx_codec_vp8_cx_algo,
#endif
#if CONFIG_VP9_ENCODER
    &vpx_codec_vp9_cx_algo,
#endif
  };
  uint8_t buf[1] = { 0 };
  vpx_image_t img;
  vpx_codec_ctx_t enc;
  vpx_codec_enc_cfg_t cfg;

  EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf));

  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(NULL, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(&enc, NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, NULL, 0, 0, 0, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, &img, 0, 0, 0, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_enc_config_default(NULL, NULL, 0));
  EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
            vpx_codec_enc_config_default(NULL, &cfg, 0));
  EXPECT_TRUE(vpx_codec_error(NULL) != NULL);

  for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
    SCOPED_TRACE(vpx_codec_iface_name(kCodecs[i]));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_init(NULL, kCodecs[i], NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_init(&enc, kCodecs[i], NULL, 0));
    EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
              vpx_codec_enc_config_default(kCodecs[i], &cfg, 1));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(kCodecs[i], &cfg, 0));
    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, kCodecs[i], &cfg, 0));
    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, NULL, 0, 0, 0, 0));

    EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
  }
}

TEST(EncodeAPI, HighBitDepthCapability) {
// VP8 should not claim VP9 HBD as a capability.
#if CONFIG_VP8_ENCODER
  const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo);
  EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
#endif

#if CONFIG_VP9_ENCODER
  const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo);
#if CONFIG_VP9_HIGHBITDEPTH
  EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
#else
  EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
#endif
#endif
}

#if CONFIG_VP8_ENCODER
TEST(EncodeAPI, DISABLED_ImageSizeSetting) {
  const int width = 711;
  const int height = 360;
  const int bps = 12;
  vpx_image_t img;
  vpx_codec_ctx_t enc;
  vpx_codec_enc_cfg_t cfg;
  uint8_t *img_buf = reinterpret_cast<uint8_t *>(
      calloc(width * height * bps / 8, sizeof(*img_buf)));
  vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0);

  cfg.g_w = width;
  cfg.g_h = height;

  vpx_img_wrap(&img, VPX_IMG_FMT_I420, width, height, 1, img_buf);

  vpx_codec_enc_init(&enc, vpx_codec_vp8_cx(), &cfg, 0);

  EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, &img, 0, 1, 0, 0));

  free(img_buf);

  vpx_codec_destroy(&enc);
}
#endif

}  // namespace
<|endoftext|>


<commit_before>#if defined(_WIN32) || defined(__WIN32__)

#include <unistd.h>
#include <windows.h>
#include "Files.hpp"

void	*Files::open(const char *filename)
{
}

void	*Files::next(void *handle, const char *sym)
{
}

bool	Files::close(void *handle)
{
}

#endif
<commit_msg>first try of windows version<commit_after>#if defined(_WIN32) || defined(__WIN32__)

#include <cstring>
#include <cstddef>
#include <windows.h>
#include "Files.hpp"

void	*Files::first(const char *dirname, char **filename)
{
  void			*dir = NULL;
  WIN32_FIND_DATA	handle = NULL;

  if ((dir = FindFirstFile(dirname, &handle)) == INVALID_HANDLE_VALUE)
    return (NULL);
  *filename = new char[256];
  memcpy(*filename, handle.cFileName, 256);
  return (dir);
}

char *Files::next(void *dir)
{
  char			*filename = new char[256];
  WIN32_FIND_DATA	data = NULL;

  if (FindNextFile(dirname, &handle) == 0)
    return (NULL);
  memcpy(filename, handle.cFileName, 256);
  return (filename);
}

bool	Files::close(void *dir)
{
  bool	closed = false;

  closed = (FindFree(dir) != 0);
  return (closed);
}

#endif
<|endoftext|>


<commit_before>// [[Rcpp::depends(BH)]]

#include "Random.h"

#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>

#include <boost/random/mersenne_twister.hpp>

// need -O0 to run in valgrind
#pragma GCC push_options
#pragma GCC optimize ("O0")
#include <boost/math/distributions/normal.hpp>
#include <boost/math/distributions/exponential.hpp>
#include <boost/math/distributions/gamma.hpp>
#pragma GCC pop_options

#include <stdint.h>

#define Q_GAMMA_THRESHOLD 1E-6
#define Q_GAMMA_MIN_VALUE 0.0

typedef boost::random::mt19937 RNGType;
//typedef boost::random::mt11213b RNGType; // should be faster

static RNGType rng;

void gaps::random::save(Archive &ar)
{
    ar << rng;
}

void gaps::random::load(Archive &ar)
{
    ar >> rng;
}

void gaps::random::setSeed(uint32_t seed)
{
    rng.seed(seed);
}

float gaps::random::normal(float mean, float var)
{
    boost::random::normal_distribution<float> dist(mean, var);
    return dist(rng);
}

int gaps::random::poisson(float lambda)
{
    boost::random::poisson_distribution<> dist(lambda);
    return dist(rng);
}

float gaps::random::exponential(float lambda)
{
    boost::random::exponential_distribution<> dist(lambda);
    return dist(rng);
}

float gaps::random::uniform()
{
    boost::random::uniform_01<RNGType&> dist(rng); // could be moved out
    return dist();
}

float gaps::random::uniform(float a, float b)
{
    if (a == b)
    {
        return a;
    }
    else
    {
        boost::random::uniform_real_distribution<> dist(a,b);
        return dist(rng);
    }
}

uint64_t gaps::random::uniform64()
{
    boost::random::uniform_int_distribution<uint64_t> dist(0,
        std::numeric_limits<uint64_t>::max());
    return dist(rng);
}

uint64_t gaps::random::uniform64(uint64_t a, uint64_t b)
{
    if (a == b)
    {
        return a;
    }
    else
    {
        boost::random::uniform_int_distribution<uint64_t> dist(a,b);
        return dist(rng);
    }
}

float gaps::random::d_gamma(float d, float shape, float scale)
{
    boost::math::gamma_distribution<> gam(shape, scale);
    return pdf(gam, d);
}

float gaps::random::p_gamma(float p, float shape, float scale)
{
    boost::math::gamma_distribution<> gam(shape, scale);
    return cdf(gam, p);
}

float gaps::random::q_gamma(float q, float shape, float scale)
{
    if (q < Q_GAMMA_THRESHOLD)
    {
        return Q_GAMMA_MIN_VALUE;
    }
    else
    {
        boost::math::gamma_distribution<> gam(shape, scale);
        return quantile(gam, q);
    }
}

float gaps::random::d_norm(float d, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return pdf(norm, d);
}

float gaps::random::q_norm(float q, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return quantile(norm, q);
}

float gaps::random::p_norm(float p, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return cdf(norm, p);
}
<commit_msg>optimization flag around boost libraries<commit_after>// [[Rcpp::depends(BH)]]

#include "Random.h"

#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>

#include <boost/random/mersenne_twister.hpp>

// need -O0 to run in valgrind, -O2 for performance
#pragma GCC push_options
#pragma GCC optimize ("O2")
#include <boost/math/distributions/normal.hpp>
#include <boost/math/distributions/exponential.hpp>
#include <boost/math/distributions/gamma.hpp>
#pragma GCC pop_options

#include <stdint.h>

#define Q_GAMMA_THRESHOLD 1E-6
#define Q_GAMMA_MIN_VALUE 0.0

typedef boost::random::mt19937 RNGType;
//typedef boost::random::mt11213b RNGType; // should be faster

static RNGType rng;

void gaps::random::save(Archive &ar)
{
    ar << rng;
}

void gaps::random::load(Archive &ar)
{
    ar >> rng;
}

void gaps::random::setSeed(uint32_t seed)
{
    rng.seed(seed);
}

float gaps::random::normal(float mean, float var)
{
    boost::random::normal_distribution<float> dist(mean, var);
    return dist(rng);
}

int gaps::random::poisson(float lambda)
{
    boost::random::poisson_distribution<> dist(lambda);
    return dist(rng);
}

float gaps::random::exponential(float lambda)
{
    boost::random::exponential_distribution<> dist(lambda);
    return dist(rng);
}

float gaps::random::uniform()
{
    boost::random::uniform_01<RNGType&> dist(rng); // could be moved out
    return dist();
}

float gaps::random::uniform(float a, float b)
{
    if (a == b)
    {
        return a;
    }
    else
    {
        boost::random::uniform_real_distribution<> dist(a,b);
        return dist(rng);
    }
}

uint64_t gaps::random::uniform64()
{
    boost::random::uniform_int_distribution<uint64_t> dist(0,
        std::numeric_limits<uint64_t>::max());
    return dist(rng);
}

uint64_t gaps::random::uniform64(uint64_t a, uint64_t b)
{
    if (a == b)
    {
        return a;
    }
    else
    {
        boost::random::uniform_int_distribution<uint64_t> dist(a,b);
        return dist(rng);
    }
}

float gaps::random::d_gamma(float d, float shape, float scale)
{
    boost::math::gamma_distribution<> gam(shape, scale);
    return pdf(gam, d);
}

float gaps::random::p_gamma(float p, float shape, float scale)
{
    boost::math::gamma_distribution<> gam(shape, scale);
    return cdf(gam, p);
}

float gaps::random::q_gamma(float q, float shape, float scale)
{
    if (q < Q_GAMMA_THRESHOLD)
    {
        return Q_GAMMA_MIN_VALUE;
    }
    else
    {
        boost::math::gamma_distribution<> gam(shape, scale);
        return quantile(gam, q);
    }
}

float gaps::random::d_norm(float d, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return pdf(norm, d);
}

float gaps::random::q_norm(float q, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return quantile(norm, q);
}

float gaps::random::p_norm(float p, float mean, float sd)
{
    boost::math::normal_distribution<> norm(mean, sd);
    return cdf(norm, p);
}
<|endoftext|>


<commit_before>//===--- GlobalSymbolBuilderMain.cpp -----------------------------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// GlobalSymbolBuilder is a tool to generate YAML-format symbols across the
// whole project. This tools is for **experimental** only. Don't use it in
// production code.
//
//===---------------------------------------------------------------------===//

#include "index/CanonicalIncludes.h"
#include "index/Index.h"
#include "index/Merge.h"
#include "index/SymbolCollector.h"
#include "index/SymbolYAML.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/Index/IndexingAction.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Execution.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/YAMLTraits.h"

using namespace llvm;
using namespace clang::tooling;
using clang::clangd::SymbolSlab;

namespace clang {
namespace clangd {
namespace {

static llvm::cl::opt<std::string> AssumedHeaderDir(
    "assume-header-dir",
    llvm::cl::desc("The index includes header that a symbol is defined in. "
                   "If the absolute path cannot be determined (e.g. an "
                   "in-memory VFS) then the relative path is resolved against "
                   "this directory, which must be absolute. If this flag is "
                   "not given, such headers will have relative paths."),
    llvm::cl::init(""));

class SymbolIndexActionFactory : public tooling::FrontendActionFactory {
public:
  SymbolIndexActionFactory(tooling::ExecutionContext *Ctx) : Ctx(Ctx) {}

  clang::FrontendAction *create() override {
    // Wraps the index action and reports collected symbols to the execution
    // context at the end of each translation unit.
    class WrappedIndexAction : public WrapperFrontendAction {
    public:
      WrappedIndexAction(std::shared_ptr<SymbolCollector> C,
                         std::unique_ptr<CanonicalIncludes> Includes,
                         const index::IndexingOptions &Opts,
                         tooling::ExecutionContext *Ctx)
          : WrapperFrontendAction(
                index::createIndexingAction(C, Opts, nullptr)),
            Ctx(Ctx), Collector(C), Includes(std::move(Includes)),
            PragmaHandler(collectIWYUHeaderMaps(this->Includes.get())) {}

      std::unique_ptr<ASTConsumer>
      CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
        CI.getPreprocessor().addCommentHandler(PragmaHandler.get());
        return WrapperFrontendAction::CreateASTConsumer(CI, InFile);
      }

      bool BeginInvocation(CompilerInstance &CI) override {
        // We want all comments, not just the doxygen ones.
        CI.getLangOpts().CommentOpts.ParseAllComments = true;
        return WrapperFrontendAction::BeginInvocation(CI);
      }

      void EndSourceFileAction() override {
        WrapperFrontendAction::EndSourceFileAction();

        const auto &CI = getCompilerInstance();
        if (CI.hasDiagnostics() &&
            (CI.getDiagnosticClient().getNumErrors() > 0)) {
          llvm::errs() << "Found errors in the translation unit. Igoring "
                          "collected symbols...\n";
          return;
        }

        auto Symbols = Collector->takeSymbols();
        for (const auto &Sym : Symbols) {
          Ctx->reportResult(Sym.ID.str(), SymbolToYAML(Sym));
        }
      }

    private:
      tooling::ExecutionContext *Ctx;
      std::shared_ptr<SymbolCollector> Collector;
      std::unique_ptr<CanonicalIncludes> Includes;
      std::unique_ptr<CommentHandler> PragmaHandler;
    };

    index::IndexingOptions IndexOpts;
    IndexOpts.SystemSymbolFilter =
        index::IndexingOptions::SystemSymbolFilterKind::All;
    IndexOpts.IndexFunctionLocals = false;
    auto CollectorOpts = SymbolCollector::Options();
    CollectorOpts.FallbackDir = AssumedHeaderDir;
    CollectorOpts.CollectIncludePath = true;
    CollectorOpts.CountReferences = true;
    auto Includes = llvm::make_unique<CanonicalIncludes>();
    addSystemHeadersMapping(Includes.get());
    CollectorOpts.Includes = Includes.get();
    return new WrappedIndexAction(
        std::make_shared<SymbolCollector>(std::move(CollectorOpts)),
        std::move(Includes), IndexOpts, Ctx);
  }

  tooling::ExecutionContext *Ctx;
};

// Combine occurrences of the same symbol across translation units.
SymbolSlab mergeSymbols(tooling::ToolResults *Results) {
  SymbolSlab::Builder UniqueSymbols;
  llvm::BumpPtrAllocator Arena;
  Symbol::Details Scratch;
  Results->forEachResult([&](llvm::StringRef Key, llvm::StringRef Value) {
    Arena.Reset();
    llvm::yaml::Input Yin(Value, &Arena);
    auto Sym = clang::clangd::SymbolFromYAML(Yin, Arena);
    clang::clangd::SymbolID ID;
    Key >> ID;
    if (const auto *Existing = UniqueSymbols.find(ID))
      UniqueSymbols.insert(mergeSymbol(*Existing, Sym, &Scratch));
    else
      UniqueSymbols.insert(Sym);
  });
  return std::move(UniqueSymbols).build();
}

} // namespace
} // namespace clangd
} // namespace clang

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);

  const char* Overview =
      "This is an **experimental** tool to generate YAML-format "
      "project-wide symbols for clangd (global code completion). It would be "
      "changed and deprecated eventually. Don't use it in production code!";
  auto Executor = clang::tooling::createExecutorFromCommandLineArgs(
      argc, argv, cl::GeneralCategory, Overview);

  if (!Executor) {
    llvm::errs() << llvm::toString(Executor.takeError()) << "\n";
    return 1;
  }

  if (!clang::clangd::AssumedHeaderDir.empty() &&
      !llvm::sys::path::is_absolute(clang::clangd::AssumedHeaderDir)) {
    llvm::errs() << "--assume-header-dir must be an absolute path.\n";
    return 1;
  }

  // Map phase: emit symbols found in each translation unit.
  auto Err = Executor->get()->execute(
      llvm::make_unique<clang::clangd::SymbolIndexActionFactory>(
          Executor->get()->getExecutionContext()));
  if (Err) {
    llvm::errs() << llvm::toString(std::move(Err)) << "\n";
  }

  // Reduce phase: combine symbols using the ID as a key.
  auto UniqueSymbols =
      clang::clangd::mergeSymbols(Executor->get()->getToolResults());

  // Output phase: emit YAML for result symbols.
  SymbolsToYAML(UniqueSymbols, llvm::outs());
  return 0;
}
<commit_msg>[clangd] only ignore collected symbols if TU has uncompilable errors.<commit_after>//===--- GlobalSymbolBuilderMain.cpp -----------------------------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// GlobalSymbolBuilder is a tool to generate YAML-format symbols across the
// whole project. This tools is for **experimental** only. Don't use it in
// production code.
//
//===---------------------------------------------------------------------===//

#include "index/CanonicalIncludes.h"
#include "index/Index.h"
#include "index/Merge.h"
#include "index/SymbolCollector.h"
#include "index/SymbolYAML.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/Index/IndexingAction.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Execution.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/YAMLTraits.h"

using namespace llvm;
using namespace clang::tooling;
using clang::clangd::SymbolSlab;

namespace clang {
namespace clangd {
namespace {

static llvm::cl::opt<std::string> AssumedHeaderDir(
    "assume-header-dir",
    llvm::cl::desc("The index includes header that a symbol is defined in. "
                   "If the absolute path cannot be determined (e.g. an "
                   "in-memory VFS) then the relative path is resolved against "
                   "this directory, which must be absolute. If this flag is "
                   "not given, such headers will have relative paths."),
    llvm::cl::init(""));

class SymbolIndexActionFactory : public tooling::FrontendActionFactory {
public:
  SymbolIndexActionFactory(tooling::ExecutionContext *Ctx) : Ctx(Ctx) {}

  clang::FrontendAction *create() override {
    // Wraps the index action and reports collected symbols to the execution
    // context at the end of each translation unit.
    class WrappedIndexAction : public WrapperFrontendAction {
    public:
      WrappedIndexAction(std::shared_ptr<SymbolCollector> C,
                         std::unique_ptr<CanonicalIncludes> Includes,
                         const index::IndexingOptions &Opts,
                         tooling::ExecutionContext *Ctx)
          : WrapperFrontendAction(
                index::createIndexingAction(C, Opts, nullptr)),
            Ctx(Ctx), Collector(C), Includes(std::move(Includes)),
            PragmaHandler(collectIWYUHeaderMaps(this->Includes.get())) {}

      std::unique_ptr<ASTConsumer>
      CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
        CI.getPreprocessor().addCommentHandler(PragmaHandler.get());
        return WrapperFrontendAction::CreateASTConsumer(CI, InFile);
      }

      bool BeginInvocation(CompilerInstance &CI) override {
        // We want all comments, not just the doxygen ones.
        CI.getLangOpts().CommentOpts.ParseAllComments = true;
        return WrapperFrontendAction::BeginInvocation(CI);
      }

      void EndSourceFileAction() override {
        WrapperFrontendAction::EndSourceFileAction();

        const auto &CI = getCompilerInstance();
        if (CI.hasDiagnostics() &&
            CI.getDiagnostics().hasUncompilableErrorOccurred()) {
          llvm::errs()
              << "Found uncompilable errors in the translation unit. Igoring "
                 "collected symbols...\n";
          return;
        }

        auto Symbols = Collector->takeSymbols();
        for (const auto &Sym : Symbols) {
          Ctx->reportResult(Sym.ID.str(), SymbolToYAML(Sym));
        }
      }

    private:
      tooling::ExecutionContext *Ctx;
      std::shared_ptr<SymbolCollector> Collector;
      std::unique_ptr<CanonicalIncludes> Includes;
      std::unique_ptr<CommentHandler> PragmaHandler;
    };

    index::IndexingOptions IndexOpts;
    IndexOpts.SystemSymbolFilter =
        index::IndexingOptions::SystemSymbolFilterKind::All;
    IndexOpts.IndexFunctionLocals = false;
    auto CollectorOpts = SymbolCollector::Options();
    CollectorOpts.FallbackDir = AssumedHeaderDir;
    CollectorOpts.CollectIncludePath = true;
    CollectorOpts.CountReferences = true;
    auto Includes = llvm::make_unique<CanonicalIncludes>();
    addSystemHeadersMapping(Includes.get());
    CollectorOpts.Includes = Includes.get();
    return new WrappedIndexAction(
        std::make_shared<SymbolCollector>(std::move(CollectorOpts)),
        std::move(Includes), IndexOpts, Ctx);
  }

  tooling::ExecutionContext *Ctx;
};

// Combine occurrences of the same symbol across translation units.
SymbolSlab mergeSymbols(tooling::ToolResults *Results) {
  SymbolSlab::Builder UniqueSymbols;
  llvm::BumpPtrAllocator Arena;
  Symbol::Details Scratch;
  Results->forEachResult([&](llvm::StringRef Key, llvm::StringRef Value) {
    Arena.Reset();
    llvm::yaml::Input Yin(Value, &Arena);
    auto Sym = clang::clangd::SymbolFromYAML(Yin, Arena);
    clang::clangd::SymbolID ID;
    Key >> ID;
    if (const auto *Existing = UniqueSymbols.find(ID))
      UniqueSymbols.insert(mergeSymbol(*Existing, Sym, &Scratch));
    else
      UniqueSymbols.insert(Sym);
  });
  return std::move(UniqueSymbols).build();
}

} // namespace
} // namespace clangd
} // namespace clang

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);

  const char* Overview =
      "This is an **experimental** tool to generate YAML-format "
      "project-wide symbols for clangd (global code completion). It would be "
      "changed and deprecated eventually. Don't use it in production code!";
  auto Executor = clang::tooling::createExecutorFromCommandLineArgs(
      argc, argv, cl::GeneralCategory, Overview);

  if (!Executor) {
    llvm::errs() << llvm::toString(Executor.takeError()) << "\n";
    return 1;
  }

  if (!clang::clangd::AssumedHeaderDir.empty() &&
      !llvm::sys::path::is_absolute(clang::clangd::AssumedHeaderDir)) {
    llvm::errs() << "--assume-header-dir must be an absolute path.\n";
    return 1;
  }

  // Map phase: emit symbols found in each translation unit.
  auto Err = Executor->get()->execute(
      llvm::make_unique<clang::clangd::SymbolIndexActionFactory>(
          Executor->get()->getExecutionContext()));
  if (Err) {
    llvm::errs() << llvm::toString(std::move(Err)) << "\n";
  }

  // Reduce phase: combine symbols using the ID as a key.
  auto UniqueSymbols =
      clang::clangd::mergeSymbols(Executor->get()->getToolResults());

  // Output phase: emit YAML for result symbols.
  SymbolsToYAML(UniqueSymbols, llvm::outs());
  return 0;
}
<|endoftext|>


<commit_before><commit_msg>-Werror,-Wunused-const-variable<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2006-2009 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 "chrome/browser/first_run.h"

#include "build/build_config.h"

// TODO(port): move more code in back from the first_run_win.cc module.

#if defined(OS_WIN)
#include "chrome/installer/util/install_util.h"
#endif

#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"

namespace {

// The kSentinelFile file absence will tell us it is a first run.
#if defined(OS_WIN)
const char kSentinelFile[] = "First Run";
#else
// On other platforms de intentionally use a different file name, so
// when the remainder of this file is implemented, we can switch to
// the proper file name and users will get the first run interface again.
const char kSentinelFile[] = "First Run Alpha";
#endif

// Gives the full path to the sentinel file. The file might not exist.
bool GetFirstRunSentinelFilePath(FilePath* path) {
  FilePath exe_path;
  if (!PathService::Get(base::DIR_EXE, &exe_path))
    return false;

  FilePath first_run_sentinel;

#if defined(OS_WIN)
  if (InstallUtil::IsPerUserInstall(exe_path.value().c_str())) {
    first_run_sentinel = exe_path;
  } else {
    if (!PathService::Get(chrome::DIR_USER_DATA, &first_run_sentinel))
      return false;
  }
#else
  // TODO(port): logic as above.  Not important for our "First Run Dev" file.
  if (!PathService::Get(chrome::DIR_USER_DATA, &first_run_sentinel))
    return false;
#endif

  first_run_sentinel = first_run_sentinel.AppendASCII(kSentinelFile);
  *path = first_run_sentinel;
  return true;
}

}  // namespace

bool FirstRun::IsChromeFirstRun() {
  // A troolean, 0 means not yet set, 1 means set to true, 2 set to false.
  static int first_run = 0;
  if (first_run != 0)
    return first_run == 1;

  FilePath first_run_sentinel;
  if (!GetFirstRunSentinelFilePath(&first_run_sentinel) ||
      file_util::PathExists(first_run_sentinel)) {
    first_run = 2;
    return false;
  }
  first_run = 1;
  return true;
}

bool FirstRun::RemoveSentinel() {
  FilePath first_run_sentinel;
  if (!GetFirstRunSentinelFilePath(&first_run_sentinel))
    return false;
  return file_util::Delete(first_run_sentinel, false);
}

bool FirstRun::CreateSentinel() {
  FilePath first_run_sentinel;
  if (!GetFirstRunSentinelFilePath(&first_run_sentinel))
    return false;
  return file_util::WriteFile(first_run_sentinel, "", 0) != -1;
}
<commit_msg>Fix mac.<commit_after>// Copyright (c) 2006-2009 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 "chrome/browser/first_run.h"

#include "build/build_config.h"

// TODO(port): move more code in back from the first_run_win.cc module.

#if defined(OS_WIN)
#include "chrome/installer/util/install_util.h"
#endif

#include "base/file_util.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"

namespace {

// The kSentinelFile file absence will tell us it is a first run.
#if defined(OS_WIN)
const char kSentinelFile[] = "First Run";
#else
// On other platforms de intentionally use a different file name, so
// when the remainder of this file is implemented, we can switch to
// the proper file name and users will get the first run interface again.
const char kSentinelFile[] = "First Run Alpha";
#endif

// Gives the full path to the sentinel file. The file might not exist.
bool GetFirstRunSentinelFilePath(FilePath* path) {
  FilePath exe_path;
  if (!PathService::Get(base::DIR_EXE, &exe_path))
    return false;

  FilePath first_run_sentinel;

#if defined(OS_WIN)
  if (InstallUtil::IsPerUserInstall(exe_path.value().c_str())) {
    first_run_sentinel = exe_path;
  } else {
    if (!PathService::Get(chrome::DIR_USER_DATA, &first_run_sentinel))
      return false;
  }
#else
  // TODO(port): logic as above.  Not important for our "First Run Dev" file.
  if (!PathService::Get(chrome::DIR_USER_DATA, &first_run_sentinel))
    return false;
#endif

  first_run_sentinel = first_run_sentinel.AppendASCII(kSentinelFile);
  *path = first_run_sentinel;
  return true;
}

}  // namespace

// TODO(port): Mac should share this code.
#if !defined(OS_MACOSX)
bool FirstRun::IsChromeFirstRun() {
  // A troolean, 0 means not yet set, 1 means set to true, 2 set to false.
  static int first_run = 0;
  if (first_run != 0)
    return first_run == 1;

  FilePath first_run_sentinel;
  if (!GetFirstRunSentinelFilePath(&first_run_sentinel) ||
      file_util::PathExists(first_run_sentinel)) {
    first_run = 2;
    return false;
  }
  first_run = 1;
  return true;
}
#endif

bool FirstRun::RemoveSentinel() {
  FilePath first_run_sentinel;
  if (!GetFirstRunSentinelFilePath(&first_run_sentinel))
    return false;
  return file_util::Delete(first_run_sentinel, false);
}

bool FirstRun::CreateSentinel() {
  FilePath first_run_sentinel;
  if (!GetFirstRunSentinelFilePath(&first_run_sentinel))
    return false;
  return file_util::WriteFile(first_run_sentinel, "", 0) != -1;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "skia/ext/bitmap_platform_device_linux.h"

#include "skia/ext/bitmap_platform_device_data.h"

#if defined(OS_OPENBSD)
#include <cairo.h>
#else
#include <cairo/cairo.h>
#endif

namespace skia {

namespace {

void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
  cairo_matrix_t cairo_matrix;
  cairo_matrix_init(&cairo_matrix,
                    SkScalarToFloat(matrix.getScaleX()),
                    SkScalarToFloat(matrix.getSkewY()),
                    SkScalarToFloat(matrix.getSkewX()),
                    SkScalarToFloat(matrix.getScaleY()),
                    SkScalarToFloat(matrix.getTranslateX()),
                    SkScalarToFloat(matrix.getTranslateY()));
  cairo_set_matrix(context, &cairo_matrix);
}

void LoadClipToContext(cairo_t* context, const SkRegion& clip) {
  cairo_reset_clip(context);

  // TODO(brettw) support non-rect clips.
  SkIRect bounding = clip.getBounds();
  cairo_rectangle(context, bounding.fLeft, bounding.fTop,
                  bounding.fRight - bounding.fLeft,
                  bounding.fBottom - bounding.fTop);
  cairo_clip(context);
}

}  // namespace

BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
    cairo_surface_t* surface)
    : surface_(surface),
      config_dirty_(true),
      transform_(SkMatrix::I()) {  // Want to load the config next time.
  bitmap_context_ = cairo_create(surface);
}

BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
  cairo_destroy(bitmap_context_);
  cairo_surface_destroy(surface_);
}

void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
    const SkMatrix& transform,
    const SkRegion& region) {
  transform_ = transform;
  clip_region_ = region;
  config_dirty_ = true;
}

void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
  if (!config_dirty_ || !bitmap_context_)
    return;  // Nothing to do.
  config_dirty_ = false;

  // Load the identity matrix since this is what our clip is relative to.
  cairo_matrix_t cairo_matrix;
  cairo_matrix_init_identity(&cairo_matrix);
  cairo_set_matrix(bitmap_context_, &cairo_matrix);

  LoadClipToContext(bitmap_context_, clip_region_);
  LoadMatrixToContext(bitmap_context_, transform_);
}

// We use this static factory function instead of the regular constructor so
// that we can create the pixel data before calling the constructor. This is
// required so that we can call the base class' constructor with the pixel
// data.
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                   bool is_opaque,
                                                   cairo_surface_t* surface) {
  SkBitmap bitmap;
  bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height,
                   cairo_image_surface_get_stride(surface));
  bitmap.setPixels(cairo_image_surface_get_data(surface));
  bitmap.setIsOpaque(is_opaque);

  // The device object will take ownership of the graphics context.
  return new BitmapPlatformDevice
      (bitmap, new BitmapPlatformDeviceData(surface));
}

BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                   bool is_opaque) {
  // This initializes the bitmap to all zeros.
  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
                                                        width, height);

  BitmapPlatformDevice* device = Create(width, height, is_opaque, surface);

#ifndef NDEBUG
  if (is_opaque)  // Fill with bright bluish green
    device->eraseColor(SkColorSetARGB(255, 0, 255, 128));
#endif

  return device;
}

BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
                                                           int height,
                                                           bool is_opaque) {
  // The Linux port always constructs initialized bitmaps, so there is no extra
  // work to perform here.
  return Create(width, height, is_opaque);
}

BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                   bool is_opaque,
                                                   uint8_t* data) {
  cairo_surface_t* surface = cairo_image_surface_create_for_data(
      data, CAIRO_FORMAT_ARGB32, width, height,
      cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));

  return Create(width, height, is_opaque, surface);
}

// The device will own the bitmap, which corresponds to also owning the pixel
// data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
BitmapPlatformDevice::BitmapPlatformDevice(
    const SkBitmap& bitmap,
    BitmapPlatformDeviceData* data)
    : SkDevice(bitmap),
      data_(data) {
  SetPlatformDevice(this, this);
}

BitmapPlatformDevice::~BitmapPlatformDevice() {
}

SkDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
    SkBitmap::Config config, int width, int height, bool isOpaque,
    Usage /*usage*/) {
  SkASSERT(config == SkBitmap::kARGB_8888_Config);
  return BitmapPlatformDevice::Create(width, height, isOpaque);
}

cairo_t* BitmapPlatformDevice::BeginPlatformPaint() {
  data_->LoadConfig();
  cairo_t* cairo = data_->bitmap_context();
  cairo_surface_t* surface = cairo_get_target(cairo);
  // Tell cairo to flush anything it has pending.
  cairo_surface_flush(surface);
  // Tell Cairo that we (probably) modified (actually, will modify) its pixel
  // buffer directly.
  cairo_surface_mark_dirty(surface);
  return cairo;
}

void BitmapPlatformDevice::DrawToNativeContext(
    PlatformSurface surface, int x, int y, const PlatformRect* src_rect) {
  // Should never be called on Linux.
  SkASSERT(false);
}

void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
                                         const SkRegion& region,
                                         const SkClipStack&) {
  data_->SetMatrixClip(transform, region);
}

}  // namespace skia
<commit_msg>return NULL if we failed to allocate a cairo surface, rather than waiting for skia to crash with a null-bitmap-ptr. The callers already check for a NULL-BitmapPlatformDevice return value.<commit_after>// Copyright (c) 2012 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 "skia/ext/bitmap_platform_device_linux.h"

#include "skia/ext/bitmap_platform_device_data.h"

#if defined(OS_OPENBSD)
#include <cairo.h>
#else
#include <cairo/cairo.h>
#endif

namespace skia {

namespace {

void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
  cairo_matrix_t cairo_matrix;
  cairo_matrix_init(&cairo_matrix,
                    SkScalarToFloat(matrix.getScaleX()),
                    SkScalarToFloat(matrix.getSkewY()),
                    SkScalarToFloat(matrix.getSkewX()),
                    SkScalarToFloat(matrix.getScaleY()),
                    SkScalarToFloat(matrix.getTranslateX()),
                    SkScalarToFloat(matrix.getTranslateY()));
  cairo_set_matrix(context, &cairo_matrix);
}

void LoadClipToContext(cairo_t* context, const SkRegion& clip) {
  cairo_reset_clip(context);

  // TODO(brettw) support non-rect clips.
  SkIRect bounding = clip.getBounds();
  cairo_rectangle(context, bounding.fLeft, bounding.fTop,
                  bounding.fRight - bounding.fLeft,
                  bounding.fBottom - bounding.fTop);
  cairo_clip(context);
}

}  // namespace

BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
    cairo_surface_t* surface)
    : surface_(surface),
      config_dirty_(true),
      transform_(SkMatrix::I()) {  // Want to load the config next time.
  bitmap_context_ = cairo_create(surface);
}

BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
  cairo_destroy(bitmap_context_);
  cairo_surface_destroy(surface_);
}

void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
    const SkMatrix& transform,
    const SkRegion& region) {
  transform_ = transform;
  clip_region_ = region;
  config_dirty_ = true;
}

void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
  if (!config_dirty_ || !bitmap_context_)
    return;  // Nothing to do.
  config_dirty_ = false;

  // Load the identity matrix since this is what our clip is relative to.
  cairo_matrix_t cairo_matrix;
  cairo_matrix_init_identity(&cairo_matrix);
  cairo_set_matrix(bitmap_context_, &cairo_matrix);

  LoadClipToContext(bitmap_context_, clip_region_);
  LoadMatrixToContext(bitmap_context_, transform_);
}

// We use this static factory function instead of the regular constructor so
// that we can create the pixel data before calling the constructor. This is
// required so that we can call the base class' constructor with the pixel
// data.
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                   bool is_opaque,
                                                   cairo_surface_t* surface) {
  SkBitmap bitmap;
  bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height,
                   cairo_image_surface_get_stride(surface));
  bitmap.setPixels(cairo_image_surface_get_data(surface));
  bitmap.setIsOpaque(is_opaque);

  // The device object will take ownership of the graphics context.
  return new BitmapPlatformDevice
      (bitmap, new BitmapPlatformDeviceData(surface));
}

BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                   bool is_opaque) {
  // This initializes the bitmap to all zeros.
  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
                                                        width, height);
  if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
    cairo_surface_destroy(surface);
    return NULL;
  }

  BitmapPlatformDevice* device = Create(width, height, is_opaque, surface);

#ifndef NDEBUG
  if (is_opaque)  // Fill with bright bluish green
    device->eraseColor(SkColorSetARGB(255, 0, 255, 128));
#endif

  return device;
}

BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
                                                           int height,
                                                           bool is_opaque) {
  // The Linux port always constructs initialized bitmaps, so there is no extra
  // work to perform here.
  return Create(width, height, is_opaque);
}

BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                   bool is_opaque,
                                                   uint8_t* data) {
  cairo_surface_t* surface = cairo_image_surface_create_for_data(
      data, CAIRO_FORMAT_ARGB32, width, height,
      cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));

  return Create(width, height, is_opaque, surface);
}

// The device will own the bitmap, which corresponds to also owning the pixel
// data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
BitmapPlatformDevice::BitmapPlatformDevice(
    const SkBitmap& bitmap,
    BitmapPlatformDeviceData* data)
    : SkDevice(bitmap),
      data_(data) {
  SetPlatformDevice(this, this);
}

BitmapPlatformDevice::~BitmapPlatformDevice() {
}

SkDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
    SkBitmap::Config config, int width, int height, bool isOpaque,
    Usage /*usage*/) {
  SkASSERT(config == SkBitmap::kARGB_8888_Config);
  return BitmapPlatformDevice::Create(width, height, isOpaque);
}

cairo_t* BitmapPlatformDevice::BeginPlatformPaint() {
  data_->LoadConfig();
  cairo_t* cairo = data_->bitmap_context();
  cairo_surface_t* surface = cairo_get_target(cairo);
  // Tell cairo to flush anything it has pending.
  cairo_surface_flush(surface);
  // Tell Cairo that we (probably) modified (actually, will modify) its pixel
  // buffer directly.
  cairo_surface_mark_dirty(surface);
  return cairo;
}

void BitmapPlatformDevice::DrawToNativeContext(
    PlatformSurface surface, int x, int y, const PlatformRect* src_rect) {
  // Should never be called on Linux.
  SkASSERT(false);
}

void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
                                         const SkRegion& region,
                                         const SkClipStack&) {
  data_->SetMatrixClip(transform, region);
}

}  // namespace skia
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "chrome/common/nacl_types.h"

namespace nacl {

NaClStartParams::NaClStartParams()
    : validation_cache_enabled(false),
      enable_exception_handling(false),
      enable_debug_stub(false),
      enable_ipc_proxy(false),
      uses_irt(false),
      enable_dyncode_syscalls(false) {
}

NaClStartParams::~NaClStartParams() {
}

NaClLaunchParams::NaClLaunchParams()
    : render_view_id(0),
      permission_bits(0),
      uses_irt(false),
      enable_dyncode_syscalls(false),
      enable_exception_handling(false)  {
}

NaClLaunchParams::NaClLaunchParams(const std::string& manifest_url_,
                                   int render_view_id_,
                                   uint32 permission_bits_,
                                   bool uses_irt_,
                                   bool enable_dyncode_syscalls_,
                                   bool enable_exception_handling_)
    : manifest_url(manifest_url_),
      render_view_id(render_view_id_),
      permission_bits(permission_bits_),
      uses_irt(uses_irt_),
      enable_dyncode_syscalls(enable_dyncode_syscalls_),
      enable_exception_handling(enable_exception_handling_)  {
}

NaClLaunchParams::NaClLaunchParams(const NaClLaunchParams& l) {
  manifest_url = l.manifest_url;
  render_view_id = l.render_view_id;
  permission_bits = l.permission_bits;
  uses_irt = l.uses_irt;
  enable_dyncode_syscalls = l.enable_dyncode_syscalls;
  enable_exception_handling = l.enable_exception_handling;
}

NaClLaunchParams::~NaClLaunchParams() {
}

}  // namespace nacl
<commit_msg>Remove odd trailing underscores<commit_after>// Copyright (c) 2012 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 "chrome/common/nacl_types.h"

namespace nacl {

NaClStartParams::NaClStartParams()
    : validation_cache_enabled(false),
      enable_exception_handling(false),
      enable_debug_stub(false),
      enable_ipc_proxy(false),
      uses_irt(false),
      enable_dyncode_syscalls(false) {
}

NaClStartParams::~NaClStartParams() {
}

NaClLaunchParams::NaClLaunchParams()
    : render_view_id(0),
      permission_bits(0),
      uses_irt(false),
      enable_dyncode_syscalls(false),
      enable_exception_handling(false)  {
}

NaClLaunchParams::NaClLaunchParams(const std::string& manifest_url,
                                   int render_view_id,
                                   uint32 permission_bits,
                                   bool uses_irt,
                                   bool enable_dyncode_syscalls,
                                   bool enable_exception_handling)
    : manifest_url(manifest_url),
      render_view_id(render_view_id),
      permission_bits(permission_bits),
      uses_irt(uses_irt),
      enable_dyncode_syscalls(enable_dyncode_syscalls),
      enable_exception_handling(enable_exception_handling)  {
}

NaClLaunchParams::NaClLaunchParams(const NaClLaunchParams& l) {
  manifest_url = l.manifest_url;
  render_view_id = l.render_view_id;
  permission_bits = l.permission_bits;
  uses_irt = l.uses_irt;
  enable_dyncode_syscalls = l.enable_dyncode_syscalls;
  enable_exception_handling = l.enable_exception_handling;
}

NaClLaunchParams::~NaClLaunchParams() {
}

}  // namespace nacl
<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2016-2017 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "RenderManager.h"
#include <QApplication>
#include <QMutexLocker>
#include <QProgressDialog>
#include "CaptureContext.h"
#include "QRDUtils.h"

RenderManager::RenderManager()
{
  m_Running = false;
  m_Thread = NULL;
}

RenderManager::~RenderManager()
{
}

void RenderManager::OpenCapture(const QString &logfile, float *progress)
{
  if(m_Running)
    return;

  m_ProxyRenderer = -1;
  m_ReplayHost = "";
  m_Logfile = logfile;
  m_Progress = progress;

  *progress = 0.0f;

  m_Thread = new LambdaThread([this]() { run(); });
  m_Thread->start(QThread::HighestPriority);

  while(m_Thread->isRunning() && !m_Running)
  {
  }
}

void RenderManager::DeleteCapture(const QString &logfile, bool local)
{
  if(IsRunning())
  {
    AsyncInvoke([this, logfile, local](IReplayRenderer *) { DeleteCapture(logfile, local); });
    return;
  }

  if(local)
  {
    QFile::remove(logfile);
  }
  else
  {
    // this will be cleaned up automatically when the remote connection
    // is closed.
    if(m_Remote)
    {
      QMutexLocker autolock(&m_RemoteLock);
      m_Remote->TakeOwnershipCapture(logfile.toUtf8().data());
    }
  }
}

QStringList RenderManager::GetRemoteSupport()
{
  QStringList ret;

  if(m_Remote && !IsRunning())
  {
    QMutexLocker autolock(&m_RemoteLock);

    rdctype::array<rdctype::str> supported;
    m_Remote->RemoteSupportedReplays(&supported);
    for(rdctype::str &s : supported)
      ret << ToQStr(s);
  }

  return ret;
}

void RenderManager::GetHomeFolder(bool synchronous, DirectoryBrowseMethod cb)
{
  if(!m_Remote)
    return;

  if(IsRunning() && m_Thread->isCurrentThread())
  {
    auto lambda = [cb, this](IReplayRenderer *r) {
      cb(m_Remote->GetHomeFolder().c_str(), rdctype::array<DirectoryFile>());
    };

    if(synchronous)
      BlockInvoke(lambda);
    else
      AsyncInvoke(lambda);
    return;
  }

  rdctype::str home;

  {
    QMutexLocker autolock(&m_RemoteLock);
    home = m_Remote->GetHomeFolder();
  }

  cb(home.c_str(), rdctype::array<DirectoryFile>());
}

bool RenderManager::ListFolder(QString path, bool synchronous, DirectoryBrowseMethod cb)
{
  if(!m_Remote)
    return false;

  QByteArray pathUTF8 = path.toUtf8();

  if(IsRunning() && m_Thread->isCurrentThread())
  {
    auto lambda = [cb, pathUTF8, this](IReplayRenderer *r) {
      cb(pathUTF8.data(), m_Remote->ListFolder(pathUTF8.data()));
    };

    if(synchronous)
      BlockInvoke(lambda);
    else
      AsyncInvoke(lambda);
    return true;
  }

  rdctype::array<DirectoryFile> contents;

  // prevent pings while fetching remote FS data
  {
    QMutexLocker autolock(&m_RemoteLock);
    contents = m_Remote->ListFolder(pathUTF8.data());
  }

  cb(pathUTF8.data(), contents);

  return true;
}

QString RenderManager::CopyCaptureToRemote(const QString &localpath, QWidget *window)
{
  if(!m_Remote)
    return "";

  QString remotepath = "";

  bool copied = false;
  float progress = 0.0f;

  auto lambda = [this, localpath, &remotepath, &progress, &copied](IReplayRenderer *r) {
    QMutexLocker autolock(&m_RemoteLock);
    remotepath = m_Remote->CopyCaptureToRemote(localpath.toUtf8().data(), &progress);
    copied = true;
  };

  // we should never have the thread running at this point, but let's be safe.
  if(IsRunning())
  {
    AsyncInvoke(lambda);
  }
  else
  {
    LambdaThread *thread = new LambdaThread([&lambda]() { lambda(NULL); });
    thread->selfDelete(true);
    thread->start();
  }

  ShowProgressDialog(window, QApplication::translate("RenderManager", "Transferring..."),
                     [&copied]() { return copied; }, [&progress]() { return progress; });

  return remotepath;
}

void RenderManager::CopyCaptureFromRemote(const QString &remotepath, const QString &localpath,
                                          QWidget *window)
{
  if(!m_Remote)
    return;

  bool copied = false;
  float progress = 0.0f;

  auto lambda = [this, localpath, remotepath, &progress, &copied](IReplayRenderer *r) {
    QMutexLocker autolock(&m_RemoteLock);
    m_Remote->CopyCaptureFromRemote(remotepath.toUtf8().data(), localpath.toUtf8().data(), &progress);
    copied = true;
  };

  // we should never have the thread running at this point, but let's be safe.
  if(IsRunning())
  {
    AsyncInvoke(lambda);
  }
  else
  {
    LambdaThread *thread = new LambdaThread([&lambda]() { lambda(NULL); });
    thread->selfDelete(true);
    thread->start();
  }

  ShowProgressDialog(window, QApplication::translate("RenderManager", "Transferring..."),
                     [&copied]() { return copied; }, [&progress]() { return progress; });
}

bool RenderManager::IsRunning()
{
  return m_Thread && m_Thread->isRunning() && m_Running;
}

void RenderManager::AsyncInvoke(const QString &tag, RenderManager::InvokeMethod m)
{
  {
    QMutexLocker autolock(&m_RenderLock);
    for(int i = 0; i < m_RenderQueue.count();)
    {
      if(m_RenderQueue[i]->tag == tag)
      {
        InvokeHandle *cmd = m_RenderQueue.takeAt(i);
        if(cmd->selfdelete)
          delete cmd;
      }
      else
      {
        i++;
      }
    }
  }

  InvokeHandle *cmd = new InvokeHandle(m, tag);
  cmd->selfdelete = true;

  PushInvoke(cmd);
}

void RenderManager::AsyncInvoke(RenderManager::InvokeMethod m)
{
  InvokeHandle *cmd = new InvokeHandle(m);
  cmd->selfdelete = true;

  PushInvoke(cmd);
}

void RenderManager::BlockInvoke(RenderManager::InvokeMethod m)
{
  InvokeHandle *cmd = new InvokeHandle(m);

  PushInvoke(cmd);

  for(;;)
  {
    if(cmd->processed.tryAcquire())
      break;
  }

  delete cmd;
}

void RenderManager::CloseThread()
{
  m_Running = false;

  m_RenderCondition.wakeAll();

  if(m_Thread == NULL)
    return;

  // wait for the thread to close and clean up
  while(m_Thread->isRunning())
  {
  }

  m_Thread->deleteLater();
  m_Thread = NULL;
}

ReplayCreateStatus RenderManager::ConnectToRemoteServer(RemoteHost *host)
{
  ReplayCreateStatus status =
      RENDERDOC_CreateRemoteServerConnection(host->Hostname.toUtf8().data(), 0, &m_Remote);

  m_RemoteHost = host;

  if(status == eReplayCreate_Success)
  {
    m_RemoteHost->Connected = true;
    return status;
  }

  return status;
}

void RenderManager::DisconnectFromRemoteServer()
{
  if(m_RemoteHost)
    m_RemoteHost->Connected = false;

  if(m_Remote)
  {
    QMutexLocker autolock(&m_RemoteLock);
    m_Remote->ShutdownConnection();
  }

  m_RemoteHost = NULL;
  m_Remote = NULL;
}

void RenderManager::ShutdownServer()
{
  if(m_Remote)
  {
    QMutexLocker autolock(&m_RemoteLock);
    m_Remote->ShutdownServerAndConnection();
  }

  m_Remote = NULL;
}

void RenderManager::PingRemote()
{
  if(!m_Remote)
    return;

  if(m_RemoteLock.tryLock(0))
  {
    if(!IsRunning() || m_Thread->isCurrentThread())
    {
      if(!m_Remote->Ping())
        m_RemoteHost->ServerRunning = false;
    }
    m_RemoteLock.unlock();
  }
}

uint32_t RenderManager::ExecuteAndInject(const QString &exe, const QString &workingDir,
                                         const QString &cmdLine,
                                         const QList<EnvironmentModification> &env,
                                         const QString &logfile, CaptureOptions opts)
{
  void *envList = RENDERDOC_MakeEnvironmentModificationList(env.size());

  for(int i = 0; i < env.size(); i++)
    RENDERDOC_SetEnvironmentModification(envList, i, env[i].variable.toUtf8().data(),
                                         env[i].value.toUtf8().data(), env[i].type, env[i].separator);

  uint32_t ret = 0;

  if(m_Remote)
  {
    QMutexLocker autolock(&m_RemoteLock);
    ret = m_Remote->ExecuteAndInject(exe.toUtf8().data(), workingDir.toUtf8().data(),
                                     cmdLine.toUtf8().data(), envList, &opts);
  }
  else
  {
    ret = RENDERDOC_ExecuteAndInject(exe.toUtf8().data(), workingDir.toUtf8().data(),
                                     cmdLine.toUtf8().data(), envList, logfile.toUtf8().data(),
                                     &opts, false);
  }

  RENDERDOC_FreeEnvironmentModificationList(envList);

  return ret;
}

void RenderManager::PushInvoke(RenderManager::InvokeHandle *cmd)
{
  if(m_Thread == NULL || !m_Thread->isRunning() || !m_Running)
  {
    if(cmd->selfdelete)
      delete cmd;
    else
      cmd->processed.release();
    return;
  }

  QMutexLocker autolock(&m_RenderLock);
  m_RenderQueue.enqueue(cmd);
  m_RenderCondition.wakeAll();
}

void RenderManager::run()
{
  IReplayRenderer *renderer = NULL;

  if(m_Remote)
    m_CreateStatus = m_Remote->OpenCapture(~0U, m_Logfile.toUtf8().data(), m_Progress, &renderer);
  else
    m_CreateStatus = RENDERDOC_CreateReplayRenderer(m_Logfile.toUtf8().data(), m_Progress, &renderer);

  if(renderer == NULL)
    return;

  qInfo() << "QRenderDoc - renderer created for" << m_Logfile;

  m_Running = true;

  // main render command loop
  while(m_Running)
  {
    InvokeHandle *cmd = NULL;

    // wait for the condition to be woken, grab top of current queue,
    // unlock again.
    {
      QMutexLocker autolock(&m_RenderLock);
      if(m_RenderQueue.isEmpty())
        m_RenderCondition.wait(&m_RenderLock, 10);

      if(!m_RenderQueue.isEmpty())
        cmd = m_RenderQueue.dequeue();
    }

    if(cmd == NULL)
      continue;

    if(cmd->method != NULL)
      cmd->method(renderer);

    // if it's a throwaway command, delete it
    if(cmd->selfdelete)
      delete cmd;
    else
      cmd->processed.release();
  }

  // clean up anything left in the queue
  {
    QQueue<InvokeHandle *> queue;

    {
      QMutexLocker autolock(&m_RenderLock);
      m_RenderQueue.swap(queue);
    }

    for(InvokeHandle *cmd : queue)
    {
      if(cmd == NULL)
        continue;

      if(cmd->selfdelete)
        delete cmd;
      else
        cmd->processed.release();
    }
  }

  // close the core renderer
  if(m_Remote)
    m_Remote->CloseCapture(renderer);
  else
    renderer->Shutdown();
}
<commit_msg>Don't spinlock when waiting for blocking render commands<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2016-2017 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "RenderManager.h"
#include <QApplication>
#include <QMutexLocker>
#include <QProgressDialog>
#include "CaptureContext.h"
#include "QRDUtils.h"

RenderManager::RenderManager()
{
  m_Running = false;
  m_Thread = NULL;
}

RenderManager::~RenderManager()
{
}

void RenderManager::OpenCapture(const QString &logfile, float *progress)
{
  if(m_Running)
    return;

  m_ProxyRenderer = -1;
  m_ReplayHost = "";
  m_Logfile = logfile;
  m_Progress = progress;

  *progress = 0.0f;

  m_Thread = new LambdaThread([this]() { run(); });
  m_Thread->start(QThread::HighestPriority);

  while(m_Thread->isRunning() && !m_Running)
  {
  }
}

void RenderManager::DeleteCapture(const QString &logfile, bool local)
{
  if(IsRunning())
  {
    AsyncInvoke([this, logfile, local](IReplayRenderer *) { DeleteCapture(logfile, local); });
    return;
  }

  if(local)
  {
    QFile::remove(logfile);
  }
  else
  {
    // this will be cleaned up automatically when the remote connection
    // is closed.
    if(m_Remote)
    {
      QMutexLocker autolock(&m_RemoteLock);
      m_Remote->TakeOwnershipCapture(logfile.toUtf8().data());
    }
  }
}

QStringList RenderManager::GetRemoteSupport()
{
  QStringList ret;

  if(m_Remote && !IsRunning())
  {
    QMutexLocker autolock(&m_RemoteLock);

    rdctype::array<rdctype::str> supported;
    m_Remote->RemoteSupportedReplays(&supported);
    for(rdctype::str &s : supported)
      ret << ToQStr(s);
  }

  return ret;
}

void RenderManager::GetHomeFolder(bool synchronous, DirectoryBrowseMethod cb)
{
  if(!m_Remote)
    return;

  if(IsRunning() && m_Thread->isCurrentThread())
  {
    auto lambda = [cb, this](IReplayRenderer *r) {
      cb(m_Remote->GetHomeFolder().c_str(), rdctype::array<DirectoryFile>());
    };

    if(synchronous)
      BlockInvoke(lambda);
    else
      AsyncInvoke(lambda);
    return;
  }

  rdctype::str home;

  {
    QMutexLocker autolock(&m_RemoteLock);
    home = m_Remote->GetHomeFolder();
  }

  cb(home.c_str(), rdctype::array<DirectoryFile>());
}

bool RenderManager::ListFolder(QString path, bool synchronous, DirectoryBrowseMethod cb)
{
  if(!m_Remote)
    return false;

  QByteArray pathUTF8 = path.toUtf8();

  if(IsRunning() && m_Thread->isCurrentThread())
  {
    auto lambda = [cb, pathUTF8, this](IReplayRenderer *r) {
      cb(pathUTF8.data(), m_Remote->ListFolder(pathUTF8.data()));
    };

    if(synchronous)
      BlockInvoke(lambda);
    else
      AsyncInvoke(lambda);
    return true;
  }

  rdctype::array<DirectoryFile> contents;

  // prevent pings while fetching remote FS data
  {
    QMutexLocker autolock(&m_RemoteLock);
    contents = m_Remote->ListFolder(pathUTF8.data());
  }

  cb(pathUTF8.data(), contents);

  return true;
}

QString RenderManager::CopyCaptureToRemote(const QString &localpath, QWidget *window)
{
  if(!m_Remote)
    return "";

  QString remotepath = "";

  bool copied = false;
  float progress = 0.0f;

  auto lambda = [this, localpath, &remotepath, &progress, &copied](IReplayRenderer *r) {
    QMutexLocker autolock(&m_RemoteLock);
    remotepath = m_Remote->CopyCaptureToRemote(localpath.toUtf8().data(), &progress);
    copied = true;
  };

  // we should never have the thread running at this point, but let's be safe.
  if(IsRunning())
  {
    AsyncInvoke(lambda);
  }
  else
  {
    LambdaThread *thread = new LambdaThread([&lambda]() { lambda(NULL); });
    thread->selfDelete(true);
    thread->start();
  }

  ShowProgressDialog(window, QApplication::translate("RenderManager", "Transferring..."),
                     [&copied]() { return copied; }, [&progress]() { return progress; });

  return remotepath;
}

void RenderManager::CopyCaptureFromRemote(const QString &remotepath, const QString &localpath,
                                          QWidget *window)
{
  if(!m_Remote)
    return;

  bool copied = false;
  float progress = 0.0f;

  auto lambda = [this, localpath, remotepath, &progress, &copied](IReplayRenderer *r) {
    QMutexLocker autolock(&m_RemoteLock);
    m_Remote->CopyCaptureFromRemote(remotepath.toUtf8().data(), localpath.toUtf8().data(), &progress);
    copied = true;
  };

  // we should never have the thread running at this point, but let's be safe.
  if(IsRunning())
  {
    AsyncInvoke(lambda);
  }
  else
  {
    LambdaThread *thread = new LambdaThread([&lambda]() { lambda(NULL); });
    thread->selfDelete(true);
    thread->start();
  }

  ShowProgressDialog(window, QApplication::translate("RenderManager", "Transferring..."),
                     [&copied]() { return copied; }, [&progress]() { return progress; });
}

bool RenderManager::IsRunning()
{
  return m_Thread && m_Thread->isRunning() && m_Running;
}

void RenderManager::AsyncInvoke(const QString &tag, RenderManager::InvokeMethod m)
{
  {
    QMutexLocker autolock(&m_RenderLock);
    for(int i = 0; i < m_RenderQueue.count();)
    {
      if(m_RenderQueue[i]->tag == tag)
      {
        InvokeHandle *cmd = m_RenderQueue.takeAt(i);
        if(cmd->selfdelete)
          delete cmd;
      }
      else
      {
        i++;
      }
    }
  }

  InvokeHandle *cmd = new InvokeHandle(m, tag);
  cmd->selfdelete = true;

  PushInvoke(cmd);
}

void RenderManager::AsyncInvoke(RenderManager::InvokeMethod m)
{
  InvokeHandle *cmd = new InvokeHandle(m);
  cmd->selfdelete = true;

  PushInvoke(cmd);
}

void RenderManager::BlockInvoke(RenderManager::InvokeMethod m)
{
  InvokeHandle *cmd = new InvokeHandle(m);

  PushInvoke(cmd);

  cmd->processed.acquire();

  delete cmd;
}

void RenderManager::CloseThread()
{
  m_Running = false;

  m_RenderCondition.wakeAll();

  if(m_Thread == NULL)
    return;

  // wait for the thread to close and clean up
  while(m_Thread->isRunning())
  {
  }

  m_Thread->deleteLater();
  m_Thread = NULL;
}

ReplayCreateStatus RenderManager::ConnectToRemoteServer(RemoteHost *host)
{
  ReplayCreateStatus status =
      RENDERDOC_CreateRemoteServerConnection(host->Hostname.toUtf8().data(), 0, &m_Remote);

  m_RemoteHost = host;

  if(status == eReplayCreate_Success)
  {
    m_RemoteHost->Connected = true;
    return status;
  }

  return status;
}

void RenderManager::DisconnectFromRemoteServer()
{
  if(m_RemoteHost)
    m_RemoteHost->Connected = false;

  if(m_Remote)
  {
    QMutexLocker autolock(&m_RemoteLock);
    m_Remote->ShutdownConnection();
  }

  m_RemoteHost = NULL;
  m_Remote = NULL;
}

void RenderManager::ShutdownServer()
{
  if(m_Remote)
  {
    QMutexLocker autolock(&m_RemoteLock);
    m_Remote->ShutdownServerAndConnection();
  }

  m_Remote = NULL;
}

void RenderManager::PingRemote()
{
  if(!m_Remote)
    return;

  if(m_RemoteLock.tryLock(0))
  {
    if(!IsRunning() || m_Thread->isCurrentThread())
    {
      if(!m_Remote->Ping())
        m_RemoteHost->ServerRunning = false;
    }
    m_RemoteLock.unlock();
  }
}

uint32_t RenderManager::ExecuteAndInject(const QString &exe, const QString &workingDir,
                                         const QString &cmdLine,
                                         const QList<EnvironmentModification> &env,
                                         const QString &logfile, CaptureOptions opts)
{
  void *envList = RENDERDOC_MakeEnvironmentModificationList(env.size());

  for(int i = 0; i < env.size(); i++)
    RENDERDOC_SetEnvironmentModification(envList, i, env[i].variable.toUtf8().data(),
                                         env[i].value.toUtf8().data(), env[i].type, env[i].separator);

  uint32_t ret = 0;

  if(m_Remote)
  {
    QMutexLocker autolock(&m_RemoteLock);
    ret = m_Remote->ExecuteAndInject(exe.toUtf8().data(), workingDir.toUtf8().data(),
                                     cmdLine.toUtf8().data(), envList, &opts);
  }
  else
  {
    ret = RENDERDOC_ExecuteAndInject(exe.toUtf8().data(), workingDir.toUtf8().data(),
                                     cmdLine.toUtf8().data(), envList, logfile.toUtf8().data(),
                                     &opts, false);
  }

  RENDERDOC_FreeEnvironmentModificationList(envList);

  return ret;
}

void RenderManager::PushInvoke(RenderManager::InvokeHandle *cmd)
{
  if(m_Thread == NULL || !m_Thread->isRunning() || !m_Running)
  {
    if(cmd->selfdelete)
      delete cmd;
    else
      cmd->processed.release();
    return;
  }

  QMutexLocker autolock(&m_RenderLock);
  m_RenderQueue.enqueue(cmd);
  m_RenderCondition.wakeAll();
}

void RenderManager::run()
{
  IReplayRenderer *renderer = NULL;

  if(m_Remote)
    m_CreateStatus = m_Remote->OpenCapture(~0U, m_Logfile.toUtf8().data(), m_Progress, &renderer);
  else
    m_CreateStatus = RENDERDOC_CreateReplayRenderer(m_Logfile.toUtf8().data(), m_Progress, &renderer);

  if(renderer == NULL)
    return;

  qInfo() << "QRenderDoc - renderer created for" << m_Logfile;

  m_Running = true;

  // main render command loop
  while(m_Running)
  {
    InvokeHandle *cmd = NULL;

    // wait for the condition to be woken, grab top of current queue,
    // unlock again.
    {
      QMutexLocker autolock(&m_RenderLock);
      if(m_RenderQueue.isEmpty())
        m_RenderCondition.wait(&m_RenderLock, 10);

      if(!m_RenderQueue.isEmpty())
        cmd = m_RenderQueue.dequeue();
    }

    if(cmd == NULL)
      continue;

    if(cmd->method != NULL)
      cmd->method(renderer);

    // if it's a throwaway command, delete it
    if(cmd->selfdelete)
      delete cmd;
    else
      cmd->processed.release();
  }

  // clean up anything left in the queue
  {
    QQueue<InvokeHandle *> queue;

    {
      QMutexLocker autolock(&m_RenderLock);
      m_RenderQueue.swap(queue);
    }

    for(InvokeHandle *cmd : queue)
    {
      if(cmd == NULL)
        continue;

      if(cmd->selfdelete)
        delete cmd;
      else
        cmd->processed.release();
    }
  }

  // close the core renderer
  if(m_Remote)
    m_Remote->CloseCapture(renderer);
  else
    renderer->Shutdown();
}
<|endoftext|>


<commit_before>#include "../kontsevich_graph_series.hpp"
#include "../kontsevich_graph_operator.hpp"
#include "../util/partitions.hpp"
#include "../util/factorial.hpp"
#include <ginac/ginac.h>
#include <iostream>
#include <vector>
#include <fstream>
#include <limits>
#include <sstream>
using namespace std;
using namespace GiNaC;

DECLARE_FUNCTION_3P(phi)
REGISTER_FUNCTION(phi, dummy())
DECLARE_FUNCTION_3P(u)
REGISTER_FUNCTION(u, dummy())

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        cout << "Usage: " << argv[0] << " <star-product-filename>\n";
        return 1;
    }

    // Reading in star product:
    string star_product_filename(argv[1]);
    ifstream star_product_file(star_product_filename);
    parser coefficient_reader;
    KontsevichGraphSeries<ex> star_product = KontsevichGraphSeries<ex>::from_istream(star_product_file, [&coefficient_reader](std::string s) -> ex { return coefficient_reader(s); });
    size_t order = star_product.precision();

    // Make a list of weight variables
    lst weight_vars;
    for (std::pair<string, ex> pair : coefficient_reader.get_syms())
        weight_vars.append(pair.second);

    star_product.reduce();

    cout << "Number of terms in star product:\n";
    for (size_t n = 0; n <= order; ++n)
    {
        cout << "h^" << n << ": " << star_product[n].size() << " total\n";
        for (std::vector<size_t> indegrees : star_product[n].in_degrees(true))
        {
            for (size_t j = 0; j != indegrees.size(); ++j)
                cout << indegrees[j] << " ";
            cout << ": " << star_product[n][indegrees].size() << "\n";
        }
    }
    cout << "Computing associator...";
    cout.flush();
    KontsevichGraphSeries<ex> arg = { { 0, { { 1, KontsevichGraph(0, 1, {}) } }} };
    KontsevichGraphSeries<ex> assoc = star_product({ star_product, arg }) - star_product({ arg, star_product });
    cout << endl;
    cout << "Reducing associator...";
    cout.flush();
    assoc.reduce();
    cout << endl;
    cout << "Number of terms in associator:\n";
    set<ex, ex_is_less> weight_system;
    for (size_t n = 0; n <= order; ++n)
    {
        cout << "h^" << n << ":\n";
        cout << assoc[n].size() << " total\n";
        for (std::vector<size_t> indegrees : assoc[n].in_degrees(true))
        {
            for (size_t j = 0; j != indegrees.size(); ++j)
                cout << indegrees[j] << " ";
            cout << ": " << assoc[n][indegrees].size() << "\n";
            cout.flush();

            symbol x("x"), y("y"), z("z");

            std::vector<PoissonStructure> poisson_structures {
                { { x, y, z }, { {0, u(x,y,z)*phi(x,y,z).diff(z), -u(x,y,z)*phi(x,y,z).diff(y)},
                                 {-u(x,y,z)*phi(x,y,z).diff(z), 0, u(x,y,z)*phi(x,y,z).diff(x) },
                                 { u(x,y,z)*phi(x,y,z).diff(y), -u(x,y,z)*phi(x,y,z).diff(x), 0 } } },
            };

            for (PoissonStructure& poisson : poisson_structures)
            {
                typedef std::vector< std::multiset<size_t> > multi_index;
                map< multi_index, map<ex, ex, ex_is_less> > coefficients;
                for (auto& term : assoc[n][indegrees])
                {
                    map_operator_coefficients_from_graph(term.second, poisson, [&coefficients, &term](multi_index arg_derivatives, GiNaC::ex summand) {
                            ex result = (term.first * summand).expand();
                            if (result == 0)
                                return;
                            if (!is_a<add>(result))
                                result = lst(result);
                            for (auto term : result)
                            {
                                ex coefficient = 1;
                                ex derivatives = 1;
                                if (!is_a<mul>(term))
                                    term = lst(term);
                                for (auto factor : term)
                                {
                                    if  (is_a<GiNaC::function>(factor) || is_a<fderivative>(factor))
                                        derivatives *= factor;
                                    else if (is_a<numeric>(factor) || is_a<symbol>(factor))
                                        coefficient *= factor;
                                    else if (is_a<power>(factor))
                                    {
                                        if (is_a<GiNaC::function>(factor.op(0)) || is_a<fderivative>(factor.op(0)))
                                            derivatives *= factor;
                                        else if (is_a<numeric>(factor.op(0)) || is_a<symbol>(factor.op(0)))
                                            coefficient *= factor;
                                    }
                                    else
                                    {
                                        cout << "What the hell is " << factor << "?\n";
                                        // TODO: return 1;
                                    }
                                }
                                coefficients[arg_derivatives][derivatives] += coefficient;
                            }
                    });
                    cout << ".";
                    cout.flush();
                }
                cout << "\n";

                for (auto pair : coefficients)
                {
                    for (auto pair2 : pair.second)
                    {
                        ex result2 = pair2.second;
                        if (result2 == 0)
                            continue;
                        for (ex var : weight_vars)
                        {
                            if (result2.coeff(var) != 0) // first weight variable occurring in expression
                            {
                                result2 /= result2.coeff(var); // divide by its coefficient
                                break;
                            }
                        }
                        weight_system.insert(result2 == 0);
                    }
                }
            }
        }
    }
    cout << "Got system of " << weight_system.size() << " linear equations in " << weight_vars.nops() << " unknowns:\n";
    lst weight_system_lst;
    for (ex eq : weight_system)
    {
        if (eq.lhs() != eq.rhs()) // not a tautology
        {
            cout << eq << endl;
            weight_system_lst.append(eq);
        }
    }
    cout << "Solving it...\n";
    for (ex eq : lsolve(weight_system_lst, weight_vars))
        if (eq.lhs() != eq.rhs()) // not a tautology
            cout << eq << endl;
}
<commit_msg>Make `poisson_evaluate` work on arbitrary graph series<commit_after>#include "../kontsevich_graph_series.hpp"
#include "../kontsevich_graph_operator.hpp"
#include "../util/partitions.hpp"
#include "../util/factorial.hpp"
#include <ginac/ginac.h>
#include <iostream>
#include <vector>
#include <fstream>
#include <limits>
#include <sstream>
using namespace std;
using namespace GiNaC;

DECLARE_FUNCTION_3P(phi)
REGISTER_FUNCTION(phi, dummy())
DECLARE_FUNCTION_3P(u)
REGISTER_FUNCTION(u, dummy())

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        cout << "Usage: " << argv[0] << " <graph-series-filename>\n";
        return 1;
    }

    // Reading in graph series:
    string graph_series_filename(argv[1]);
    ifstream graph_series_file(graph_series_filename);
    parser coefficient_reader;
    KontsevichGraphSeries<ex> graph_series = KontsevichGraphSeries<ex>::from_istream(graph_series_file, [&coefficient_reader](std::string s) -> ex { return coefficient_reader(s); });
    size_t order = graph_series.precision();

    // Make a list of unknowns
    lst unknowns;
    for (std::pair<string, ex> pair : coefficient_reader.get_syms())
        unknowns.append(pair.second);

    cout << "Number of terms:\n";
    set<ex, ex_is_less> linear_system;
    for (size_t n = 0; n <= order; ++n)
    {
        cout << "h^" << n << ":\n";
        cout << graph_series[n].size() << " total\n";
        for (std::vector<size_t> indegrees : graph_series[n].in_degrees(true))
        {
            for (size_t j = 0; j != indegrees.size(); ++j)
                cout << indegrees[j] << " ";
            cout << ": " << graph_series[n][indegrees].size() << "\n";
            cout.flush();

            symbol x("x"), y("y"), z("z");

            std::vector<PoissonStructure> poisson_structures {
                { { x, y, z }, { {0, u(x,y,z)*phi(x,y,z).diff(z), -u(x,y,z)*phi(x,y,z).diff(y)},
                                 {-u(x,y,z)*phi(x,y,z).diff(z), 0, u(x,y,z)*phi(x,y,z).diff(x) },
                                 { u(x,y,z)*phi(x,y,z).diff(y), -u(x,y,z)*phi(x,y,z).diff(x), 0 } } },
            };

            for (PoissonStructure& poisson : poisson_structures)
            {
                typedef std::vector< std::multiset<size_t> > multi_index;
                map< multi_index, map<ex, ex, ex_is_less> > coefficients;
                for (auto& term : graph_series[n][indegrees])
                {
                    map_operator_coefficients_from_graph(term.second, poisson, [&coefficients, &term](multi_index arg_derivatives, GiNaC::ex summand) {
                            ex result = (term.first * summand).expand();
                            if (result == 0)
                                return;
                            if (!is_a<add>(result))
                                result = lst(result);
                            for (auto term : result)
                            {
                                ex coefficient = 1;
                                ex derivatives = 1;
                                if (!is_a<mul>(term))
                                    term = lst(term);
                                for (auto factor : term)
                                {
                                    if  (is_a<GiNaC::function>(factor) || is_a<fderivative>(factor))
                                        derivatives *= factor;
                                    else if (is_a<numeric>(factor) || is_a<symbol>(factor))
                                        coefficient *= factor;
                                    else if (is_a<power>(factor))
                                    {
                                        if (is_a<GiNaC::function>(factor.op(0)) || is_a<fderivative>(factor.op(0)))
                                            derivatives *= factor;
                                        else if (is_a<numeric>(factor.op(0)) || is_a<symbol>(factor.op(0)))
                                            coefficient *= factor;
                                    }
                                    else
                                    {
                                        cout << "What the hell is " << factor << "?\n";
                                        // TODO: return 1;
                                    }
                                }
                                coefficients[arg_derivatives][derivatives] += coefficient;
                            }
                    });
                    cout << ".";
                    cout.flush();
                }
                cout << "\n";

                for (auto pair : coefficients)
                {
                    for (auto pair2 : pair.second)
                    {
                        ex result2 = pair2.second;
                        if (result2 == 0)
                            continue;
                        for (ex var : unknowns)
                        {
                            if (result2.coeff(var) != 0) // first weight variable occurring in expression
                            {
                                result2 /= result2.coeff(var); // divide by its coefficient
                                break;
                            }
                        }
                        linear_system.insert(result2 == 0);
                    }
                }
            }
        }
    }
    cout << "Got system of " << linear_system.size() << " linear equations in " << unknowns.nops() << " unknowns:\n";
    lst linear_system_lst;
    for (ex eq : linear_system)
    {
        if (eq.lhs() != eq.rhs()) // not a tautology
        {
            cout << eq << endl;
            linear_system_lst.append(eq);
        }
    }
    cout << "Solving it...\n";
    for (ex eq : lsolve(linear_system_lst, unknowns))
        if (eq.lhs() != eq.rhs()) // not a tautology
            cout << eq << endl;
}
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2016, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

/// This file contains platform independent utility functions

#include <iosfwd>

#pragma once

std::string getEnvVar(const std::string &key);
<commit_msg>Add missing include Fixes build of unified backend on windows (#1977)<commit_after>/*******************************************************
 * Copyright (c) 2016, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

/// This file contains platform independent utility functions

#include <iosfwd>
#include <string>

#pragma once

std::string getEnvVar(const std::string &key);
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016-2022 Morwenn
 * SPDX-License-Identifier: MIT
 */
#include <iterator>
#include <vector>
#include <catch2/catch_test_macros.hpp>
#include <cpp-sort/probes.h>
#include <testing-tools/distributions.h>

TEST_CASE( "relations between measures of presortedness", "[probe]" )
{
    constexpr std::vector<int>::difference_type size = 100;

    std::vector<int> sequence;
    sequence.reserve(size);
    auto distribution = dist::shuffled{};
    distribution(std::back_inserter(sequence), size, 0);

    // The computer science literature lists a number of
    // relations between the results of different measures
    // of presortedness on a same sequence; the following
    // tests check that these relations are respected in
    // the library

    auto block  = cppsort::probe::block(sequence);
    auto dis    = cppsort::probe::dis(sequence);
    auto enc    = cppsort::probe::enc(sequence);
    auto exc    = cppsort::probe::exc(sequence);
    auto ham    = cppsort::probe::ham(sequence);
    auto inv    = cppsort::probe::inv(sequence);
    auto max    = cppsort::probe::max(sequence);
    auto mono   = cppsort::probe::mono(sequence);
    auto osc    = cppsort::probe::osc(sequence);
    auto rem    = cppsort::probe::rem(sequence);
    auto runs   = cppsort::probe::runs(sequence);
    auto sus    = cppsort::probe::sus(sequence);

    // Measures of Presortedness and Optimal Sorting Algorithms
    // by Heikki Mannila
    CHECK( exc <= inv );

    // A framework for adaptive sorting
    // by Ola Petersson and Alistair Moffat
    CHECK( runs <= rem + 1 );

    CHECK( exc + 1 <= ham );
    CHECK( ham <= 2 * exc );

    CHECK( max <= dis );
    CHECK( dis <= 2 * max );

    // A New Measure of Presortedness
    // by Vladimir Estivill-Castro and Derick Wood
    CHECK( dis <= inv );
    CHECK( rem <= size * (1 - 1 / (dis + 1)) );
    CHECK( inv <= size * dis / 2 );

    // Practical Adaptive Sorting
    // by Vladimir Estivill-Castro and Derick Wood
    CHECK( rem <= 2 * exc );

    // Encroaching lists as a measure of presortedness
    // by Steven S. Skiena
    CHECK( enc <= runs );
    CHECK( (2 * std::sqrt(enc) + 1) <= inv );
    CHECK( enc <= std::min(rem + 1, size - rem) );
    CHECK( 2 * enc <= exc );

    // Sorting Shuffled Monotone Sequences
    // by Christos Levcopoulos and Ola Petersson
    CHECK( sus <= runs );
    CHECK( sus <= max );
    CHECK( enc <= sus );

    // Heapsort - Adapted for Presorted Files
    // by Christos Levcopoulos and Ola Petersson
    CHECK( osc <= 4 * inv );
    CHECK( osc <= 2 * size * runs + size );
    CHECK( osc <= size * dis );

    // Sublinear Merging and Natural Mergesort
    // by Svante Carlsson, Christos Levcopoulos and Ola Petersson
    CHECK( block <= 3 * rem );

    // Computing and ranking measures of presortedness
    // by Jingsen Chen
    CHECK( enc <= dis + 1 );

    // Intuitive result: a descending run can be seen as several
    // ascending runs
    CHECK( mono <= runs );
}
<commit_msg>New test for relations between MOPs<commit_after>/*
 * Copyright (c) 2016-2022 Morwenn
 * SPDX-License-Identifier: MIT
 */
#include <iterator>
#include <vector>
#include <catch2/catch_test_macros.hpp>
#include <cpp-sort/probes.h>
#include <testing-tools/distributions.h>

TEST_CASE( "relations between measures of presortedness", "[probe]" )
{
    constexpr std::vector<int>::difference_type size = 100;

    std::vector<int> sequence;
    sequence.reserve(size);
    auto distribution = dist::shuffled{};
    distribution(std::back_inserter(sequence), size, 0);

    // The computer science literature lists a number of
    // relations between the results of different measures
    // of presortedness on a same sequence; the following
    // tests check that these relations are respected in
    // the library

    auto block  = cppsort::probe::block(sequence);
    auto dis    = cppsort::probe::dis(sequence);
    auto enc    = cppsort::probe::enc(sequence);
    auto exc    = cppsort::probe::exc(sequence);
    auto ham    = cppsort::probe::ham(sequence);
    auto inv    = cppsort::probe::inv(sequence);
    auto max    = cppsort::probe::max(sequence);
    auto mono   = cppsort::probe::mono(sequence);
    auto osc    = cppsort::probe::osc(sequence);
    auto rem    = cppsort::probe::rem(sequence);
    auto runs   = cppsort::probe::runs(sequence);
    auto sus    = cppsort::probe::sus(sequence);

    // Measures of Presortedness and Optimal Sorting Algorithms
    // by Heikki Mannila
    CHECK( exc <= inv );

    // Splitsort - an adaptive sorting algorithm
    // by Christos Levcopoulos and Ola Petersson
    CHECK( rem <= inv );

    // A framework for adaptive sorting
    // by Ola Petersson and Alistair Moffat
    CHECK( runs <= rem + 1 );

    CHECK( exc + 1 <= ham );
    CHECK( ham <= 2 * exc );

    CHECK( max <= dis );
    CHECK( dis <= 2 * max );

    // A New Measure of Presortedness
    // by Vladimir Estivill-Castro and Derick Wood
    CHECK( dis <= inv );
    CHECK( rem <= size * (1 - 1 / (dis + 1)) );
    CHECK( inv <= size * dis / 2 );

    // Practical Adaptive Sorting
    // by Vladimir Estivill-Castro and Derick Wood
    CHECK( rem <= 2 * exc );

    // Encroaching lists as a measure of presortedness
    // by Steven S. Skiena
    CHECK( enc <= runs );
    CHECK( (2 * std::sqrt(enc) + 1) <= inv );
    CHECK( enc <= std::min(rem + 1, size - rem) );
    CHECK( 2 * enc <= exc );

    // Sorting Shuffled Monotone Sequences
    // by Christos Levcopoulos and Ola Petersson
    CHECK( sus <= runs );
    CHECK( sus <= max );
    CHECK( enc <= sus );

    // Heapsort - Adapted for Presorted Files
    // by Christos Levcopoulos and Ola Petersson
    CHECK( osc <= 4 * inv );
    CHECK( osc <= 2 * size * runs + size );
    CHECK( osc <= size * dis );

    // Sublinear Merging and Natural Mergesort
    // by Svante Carlsson, Christos Levcopoulos and Ola Petersson
    CHECK( block <= 3 * rem );

    // Computing and ranking measures of presortedness
    // by Jingsen Chen
    CHECK( enc <= dis + 1 );

    // Intuitive result: a descending run can be seen as several
    // ascending runs
    CHECK( mono <= runs );
}
<|endoftext|>