<commit_before>/*
 *
 * Copyright 2015, Google Inc.
 * Copyright 2017, Jin Qing (http://blog.csdn.net/jq0123).
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <algorithm>
#include <chrono>
#include <cmath>
#include <iostream>
#include <memory>
#include <string>
#include <thread>

#include "helper.h"
#include "route_guide.grpc_cb.pb.h"

using routeguide::Point;
using routeguide::Feature;
using routeguide::Rectangle;
using routeguide::RouteSummary;
using routeguide::RouteNote;
using std::chrono::system_clock;

using FeatureVector = std::vector<Feature>;

float ConvertToRadians(float num) {
  return float(num * 3.1415926 / 180);
}

float GetDistance(const Point& start, const Point& end) {
  const float kCoordFactor = 10000000.0;
  float lat_1 = start.latitude() / kCoordFactor;
  float lat_2 = end.latitude() / kCoordFactor;
  float lon_1 = start.longitude() / kCoordFactor;
  float lon_2 = end.longitude() / kCoordFactor;
  float lat_rad_1 = ConvertToRadians(lat_1);
  float lat_rad_2 = ConvertToRadians(lat_2);
  float delta_lat_rad = ConvertToRadians(lat_2-lat_1);
  float delta_lon_rad = ConvertToRadians(lon_2-lon_1);

  float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) *
            pow(sin(delta_lon_rad/2), 2);
  float c = 2 * atan2(sqrt(a), sqrt(1-a));
  int R = 6371000; // metres

  return R * c;
}

std::string GetFeatureName(const Point& point,
                           const FeatureVector& feature_vector) {
  for (const Feature& f : feature_vector) {
    if (f.location().latitude() == point.latitude() &&
        f.location().longitude() == point.longitude()) {
      return f.name();
    }
  }
  return "";
}

class RecordRoute_ReaderImpl
    : public routeguide::RouteGuide::Service::RecordRoute_Reader {
 public:
  explicit RecordRoute_ReaderImpl(const FeatureVector& feature_vec)
      : feature_vec_(feature_vec) {}

 protected:
  void OnMsg(const Point& point) override {
    RecordRouteResult& r = record_route_result_;
    r.point_count++;
    if (!GetFeatureName(point, feature_vec_).empty()) {
      r.feature_count++;
    }
    if (r.point_count != 1) {
      r.distance += GetDistance(r.previous, point);
    }
    r.previous = point;
  }

  void OnEnd() override {
    // Make a copy.
    const RecordRouteResult r = record_route_result_;
    Replier replier = GetReplier();
    std::thread t([r, replier]() {
      system_clock::time_point end_time = system_clock::now();
      RouteSummary summary;
      summary.set_point_count(r.point_count);
      summary.set_feature_count(r.feature_count);
      summary.set_distance(static_cast<long>(r.distance));
      auto secs = std::chrono::duration_cast<std::chrono::seconds>(
          end_time - r.start_time);
      summary.set_elapsed_time(int32_t(secs.count()));

      // Delayed reply.
      std::this_thread::sleep_for(std::chrono::seconds(1));
      replier.Reply(summary);
    });
    t.detach();
  }

 private:
  const FeatureVector& feature_vec_;

  struct RecordRouteResult {
      int point_count = 0;
      int feature_count = 0;
      float distance = 0.0;
      Point previous;
      system_clock::time_point start_time = system_clock::now();
  };

  RecordRouteResult record_route_result_;
};  // class RecordRoute_ReaderImpl

class RouteGuideImpl final : public routeguide::RouteGuide::Service {
 public:
  explicit RouteGuideImpl(const std::string& db) {
    routeguide::ParseDb(db, &feature_vector_);
  }

  void GetFeature(
      const Point& point,
      GetFeature_Replier replier) override {
    Feature feature;
    feature.set_name(GetFeatureName(point, feature_vector_));
    feature.mutable_location()->CopyFrom(point);
    replier.Reply(feature);
  }

  void ListFeatures(
      const routeguide::Rectangle& rectangle,
      ListFeatures_Writer writer) override {
    const FeatureVector& feature_vector = feature_vector_;
    std::thread t([rectangle, writer, &feature_vector]() {
      auto lo = rectangle.lo();
      auto hi = rectangle.hi();
      long left = (std::min)(lo.longitude(), hi.longitude());
      long right = (std::max)(lo.longitude(), hi.longitude());
      long top = (std::max)(lo.latitude(), hi.latitude());
      long bottom = (std::min)(lo.latitude(), hi.latitude());
      for (const Feature& f : feature_vector) {
        if (f.location().longitude() >= left &&
            f.location().longitude() <= right &&
            f.location().latitude() >= bottom &&
            f.location().latitude() <= top) {
          if (!writer.Write(f)) break;
          // std::this_thread::sleep_for(std::chrono::seconds(1));
        }
      }
      // Todo: auto writer.Close(Status::OK);
    });  // thread t
    t.detach();
  }

  // Todo: Need session id.
  RecordRoute_ReaderSptr RecordRoute(
      RecordRoute_Replier replier) override {
    return std::make_shared<RecordRoute_ReaderImpl>(feature_vector_);
  }  // RecordRoute()

  RouteChat_ReaderSptr RouteChat(RouteChat_Writer writer) override {
    class Reader : public RouteChat_Reader {
     protected:
      void OnMsg(const RouteNote& msg) override {
        for (const RouteNote& n : received_notes_) {
          if (n.location().latitude() == msg.location().latitude() &&
              n.location().longitude() == msg.location().longitude()) {
            GetWriter().Write(n);
          }  // if
        }  // for
        received_notes_.push_back(msg);
      }  // OnMsg()

      void OnEnd() override {
        RouteChat_Writer writer = GetWriter();
        std::thread t([writer]() {
          std::this_thread::sleep_for(std::chrono::seconds(1));
          writer.Write(RouteNote());
        });
        t.detach();
      }  // OnEnd()

     private:
       std::vector<RouteNote> received_notes_;
    };  // class Reader

    return std::make_shared<Reader>();
  }

 private:
  FeatureVector feature_vector_;
};

void RunServer(const std::string& db_path) {
  std::string server_address("0.0.0.0:50051");
  RouteGuideImpl service(db_path);

  grpc_cb::Server svr;
  svr.AddListeningPort(server_address);
  svr.RegisterService(service);
  std::cout << "Server listening on " << server_address << std::endl;
  svr.Run();
}

int main(int argc, char** argv) {
  // Expect only arg: --db_path=path/to/route_guide_db.json.
  std::string db = routeguide::GetDbFileContent(argc, argv);
  RunServer(db);

  return 0;
}
<commit_msg>Add comment.<commit_after>/*
 *
 * Copyright 2015, Google Inc.
 * Copyright 2017, Jin Qing (http://blog.csdn.net/jq0123).
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <algorithm>
#include <chrono>
#include <cmath>
#include <iostream>
#include <memory>
#include <string>
#include <thread>

#include "helper.h"
#include "route_guide.grpc_cb.pb.h"

using routeguide::Point;
using routeguide::Feature;
using routeguide::Rectangle;
using routeguide::RouteSummary;
using routeguide::RouteNote;
using std::chrono::system_clock;

using FeatureVector = std::vector<Feature>;

float ConvertToRadians(float num) {
  return float(num * 3.1415926 / 180);
}

float GetDistance(const Point& start, const Point& end) {
  const float kCoordFactor = 10000000.0;
  float lat_1 = start.latitude() / kCoordFactor;
  float lat_2 = end.latitude() / kCoordFactor;
  float lon_1 = start.longitude() / kCoordFactor;
  float lon_2 = end.longitude() / kCoordFactor;
  float lat_rad_1 = ConvertToRadians(lat_1);
  float lat_rad_2 = ConvertToRadians(lat_2);
  float delta_lat_rad = ConvertToRadians(lat_2-lat_1);
  float delta_lon_rad = ConvertToRadians(lon_2-lon_1);

  float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) *
            pow(sin(delta_lon_rad/2), 2);
  float c = 2 * atan2(sqrt(a), sqrt(1-a));
  int R = 6371000; // metres

  return R * c;
}

std::string GetFeatureName(const Point& point,
                           const FeatureVector& feature_vector) {
  for (const Feature& f : feature_vector) {
    if (f.location().latitude() == point.latitude() &&
        f.location().longitude() == point.longitude()) {
      return f.name();
    }
  }
  return "";
}

class RecordRoute_ReaderImpl
    : public routeguide::RouteGuide::Service::RecordRoute_Reader {
 public:
  explicit RecordRoute_ReaderImpl(const FeatureVector& feature_vec)
      : feature_vec_(feature_vec) {}

 protected:
  void OnMsg(const Point& point) override {
    RecordRouteResult& r = record_route_result_;
    r.point_count++;
    if (!GetFeatureName(point, feature_vec_).empty()) {
      r.feature_count++;
    }
    if (r.point_count != 1) {
      r.distance += GetDistance(r.previous, point);
    }
    r.previous = point;
  }

  void OnEnd() override {
    // Make a copy.
    const RecordRouteResult r = record_route_result_;
    Replier replier = GetReplier();
    std::thread t([r, replier]() {
      system_clock::time_point end_time = system_clock::now();
      RouteSummary summary;
      summary.set_point_count(r.point_count);
      summary.set_feature_count(r.feature_count);
      summary.set_distance(static_cast<long>(r.distance));
      auto secs = std::chrono::duration_cast<std::chrono::seconds>(
          end_time - r.start_time);
      summary.set_elapsed_time(int32_t(secs.count()));

      // Delayed reply.
      std::this_thread::sleep_for(std::chrono::seconds(1));
      replier.Reply(summary);
    });
    t.detach();
  }

 private:
  const FeatureVector& feature_vec_;

  struct RecordRouteResult {
      int point_count = 0;
      int feature_count = 0;
      float distance = 0.0;
      Point previous;
      system_clock::time_point start_time = system_clock::now();
  };

  RecordRouteResult record_route_result_;
};  // class RecordRoute_ReaderImpl

class RouteGuideImpl final : public routeguide::RouteGuide::Service {
 public:
  explicit RouteGuideImpl(const std::string& db) {
    routeguide::ParseDb(db, &feature_vector_);
  }

  void GetFeature(
      const Point& point,
      GetFeature_Replier replier) override {
    Feature feature;
    feature.set_name(GetFeatureName(point, feature_vector_));
    feature.mutable_location()->CopyFrom(point);
    replier.Reply(feature);
  }

  void ListFeatures(
      const routeguide::Rectangle& rectangle,
      ListFeatures_Writer writer) override {
    const FeatureVector& feature_vector = feature_vector_;
    std::thread t([rectangle, writer, &feature_vector]() {
      auto lo = rectangle.lo();
      auto hi = rectangle.hi();
      long left = (std::min)(lo.longitude(), hi.longitude());
      long right = (std::max)(lo.longitude(), hi.longitude());
      long top = (std::max)(lo.latitude(), hi.latitude());
      long bottom = (std::min)(lo.latitude(), hi.latitude());
      for (const Feature& f : feature_vector) {
        if (f.location().longitude() >= left &&
            f.location().longitude() <= right &&
            f.location().latitude() >= bottom &&
            f.location().latitude() <= top) {
          if (!writer.Write(f)) break;
          // std::this_thread::sleep_for(std::chrono::seconds(1));
        }
      }
      // Todo: auto writer.Close(Status::OK);
    });  // thread t
    t.detach();
  }

  // Todo: Need session id.
  RecordRoute_ReaderSptr RecordRoute(
      RecordRoute_Replier replier) override {
    return std::make_shared<RecordRoute_ReaderImpl>(feature_vector_);
  }  // RecordRoute()

  RouteChat_ReaderSptr RouteChat(RouteChat_Writer writer) override {
    class Reader : public RouteChat_Reader {
     protected:
      void OnMsg(const RouteNote& msg) override {
        for (const RouteNote& n : received_notes_) {
          if (n.location().latitude() == msg.location().latitude() &&
              n.location().longitude() == msg.location().longitude()) {
            GetWriter().Write(n);
          }  // if
        }  // for
        received_notes_.push_back(msg);
      }  // OnMsg()

      void OnEnd() override {
        RouteChat_Writer writer = GetWriter();
        std::thread t([writer]() {
          std::this_thread::sleep_for(std::chrono::seconds(1));
          // writer can be kept and used later
          // writer.Write(RouteNote());
        });
        t.detach();
      }  // OnEnd()

     private:
       std::vector<RouteNote> received_notes_;
    };  // class Reader

    return std::make_shared<Reader>();
  }

 private:
  FeatureVector feature_vector_;
};

void RunServer(const std::string& db_path) {
  std::string server_address("0.0.0.0:50051");
  RouteGuideImpl service(db_path);

  grpc_cb::Server svr;
  svr.AddListeningPort(server_address);
  svr.RegisterService(service);
  std::cout << "Server listening on " << server_address << std::endl;
  svr.Run();
}

int main(int argc, char** argv) {
  // Expect only arg: --db_path=path/to/route_guide_db.json.
  std::string db = routeguide::GetDbFileContent(argc, argv);
  RunServer(db);

  return 0;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkMultiThreaderTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkConfigure.h"
#include "itkMultiThreader.h"

bool VerifyRange(int value, int min, int max, const char * msg)
{
  if( value < min )
    {
    std::cerr << msg << std::endl;
    return false;
    }

  if( value > max )
    {
    std::cerr << msg << std::endl;
    return false;
    }
  return true;
}

bool SetAndVerifyGlobalMaximumNumberOfThreads( int value )
{
  itk::MultiThreader::SetGlobalMaximumNumberOfThreads( value );
  return VerifyRange( itk::MultiThreader::GetGlobalMaximumNumberOfThreads(),
        1, ITK_MAX_THREADS, "Range error in MaximumNumberOfThreads");
}

bool SetAndVerifyGlobalDefaultNumberOfThreads( int value )
{
  itk::MultiThreader::SetGlobalDefaultNumberOfThreads( value );
  return VerifyRange( itk::MultiThreader::GetGlobalDefaultNumberOfThreads(),
        1, itk::MultiThreader::GetGlobalMaximumNumberOfThreads(),
        "Range error in DefaultNumberOfThreads");
}

bool SetAndVerifyNumberOfThreads( int value, itk::MultiThreader * threader )
{
  threader->SetNumberOfThreads( value );
  return VerifyRange( threader->GetNumberOfThreads(),
        1, itk::MultiThreader::GetGlobalMaximumNumberOfThreads(),
        "Range error in NumberOfThreads");
}

int itkMultiThreaderTest(int argc, char* argv[])
{
  // Choose a number of threads.
  int numberOfThreads = 10;
  if( argc > 1 )
    {
    const int nt = atoi( argv[1] );
    if(nt > 1)
      {
      numberOfThreads = nt;
      }
    }

  itk::MultiThreader::Pointer    threader = itk::MultiThreader::New();

  itk::MultiThreader::SetGlobalDefaultNumberOfThreads( numberOfThreads );

  {
  // Test settings for GlobalMaximumNumberOfThreads

  bool result = true;

  result &= SetAndVerifyGlobalMaximumNumberOfThreads( -1 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  0 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  1 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  2 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  ITK_MAX_THREADS  );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  ITK_MAX_THREADS - 1 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  ITK_MAX_THREADS + 1 );

  if( !result )
    {
    return EXIT_FAILURE;
    }

  result &= SetAndVerifyGlobalDefaultNumberOfThreads( -1 );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads(  0 );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads(  1 );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() - 1 );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() + 1 );

  if( !result )
    {
    return EXIT_FAILURE;
    }

  itk::MultiThreader::Pointer threader = itk::MultiThreader::New();

  result &= SetAndVerifyNumberOfThreads( -1, threader );
  result &= SetAndVerifyNumberOfThreads(  0, threader );
  result &= SetAndVerifyNumberOfThreads(  1, threader );
  result &= SetAndVerifyNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads(), threader );
  result &= SetAndVerifyNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() - 1, threader);
  result &= SetAndVerifyNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() + 1, threader);

  if( !result )
    {
    return EXIT_FAILURE;
    }

  }

  return EXIT_SUCCESS;
}

namespace itkMultiThreaderTestHelpers
{

void ThreadedMethod()
{

#ifdef ITK_USE_PTHREADS
// ThreadProcessIDType threadId = pthread_self();
#endif

#ifdef ITK_USE_WIN32_THREADS
// ThreadProcessIDType threadId = GetCurrentThread();
#endif

#ifdef ITK_USE_SPROC
// const ThreadProcessIDType threadId = GetCurrentThread()  ??;
#endif

}

} // end of itkMultiThreaderTestHelpers
<commit_msg>COMP: shadowed variable warning.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkMultiThreaderTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkConfigure.h"
#include "itkMultiThreader.h"

bool VerifyRange(int value, int min, int max, const char * msg)
{
  if( value < min )
    {
    std::cerr << msg << std::endl;
    return false;
    }

  if( value > max )
    {
    std::cerr << msg << std::endl;
    return false;
    }
  return true;
}

bool SetAndVerifyGlobalMaximumNumberOfThreads( int value )
{
  itk::MultiThreader::SetGlobalMaximumNumberOfThreads( value );
  return VerifyRange( itk::MultiThreader::GetGlobalMaximumNumberOfThreads(),
        1, ITK_MAX_THREADS, "Range error in MaximumNumberOfThreads");
}

bool SetAndVerifyGlobalDefaultNumberOfThreads( int value )
{
  itk::MultiThreader::SetGlobalDefaultNumberOfThreads( value );
  return VerifyRange( itk::MultiThreader::GetGlobalDefaultNumberOfThreads(),
        1, itk::MultiThreader::GetGlobalMaximumNumberOfThreads(),
        "Range error in DefaultNumberOfThreads");
}

bool SetAndVerifyNumberOfThreads( int value, itk::MultiThreader * threader )
{
  threader->SetNumberOfThreads( value );
  return VerifyRange( threader->GetNumberOfThreads(),
        1, itk::MultiThreader::GetGlobalMaximumNumberOfThreads(),
        "Range error in NumberOfThreads");
}

int itkMultiThreaderTest(int argc, char* argv[])
{
  // Choose a number of threads.
  int numberOfThreads = 10;
  if( argc > 1 )
    {
    const int nt = atoi( argv[1] );
    if(nt > 1)
      {
      numberOfThreads = nt;
      }
    }

  itk::MultiThreader::Pointer    threader = itk::MultiThreader::New();

  itk::MultiThreader::SetGlobalDefaultNumberOfThreads( numberOfThreads );

  {
  // Test settings for GlobalMaximumNumberOfThreads

  bool result = true;

  result &= SetAndVerifyGlobalMaximumNumberOfThreads( -1 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  0 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  1 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  2 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  ITK_MAX_THREADS  );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  ITK_MAX_THREADS - 1 );
  result &= SetAndVerifyGlobalMaximumNumberOfThreads(  ITK_MAX_THREADS + 1 );

  if( !result )
    {
    return EXIT_FAILURE;
    }

  result &= SetAndVerifyGlobalDefaultNumberOfThreads( -1 );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads(  0 );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads(  1 );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() - 1 );
  result &= SetAndVerifyGlobalDefaultNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() + 1 );

  if( !result )
    {
    return EXIT_FAILURE;
    }

  itk::MultiThreader::Pointer threader2 = itk::MultiThreader::New();

  result &= SetAndVerifyNumberOfThreads( -1, threader2 );
  result &= SetAndVerifyNumberOfThreads(  0, threader2 );
  result &= SetAndVerifyNumberOfThreads(  1, threader2 );
  result &= SetAndVerifyNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads(), threader2 );
  result &= SetAndVerifyNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() - 1, threader2);
  result &= SetAndVerifyNumberOfThreads( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() + 1, threader2);

  if( !result )
    {
    return EXIT_FAILURE;
    }

  }

  return EXIT_SUCCESS;
}

namespace itkMultiThreaderTestHelpers
{

void ThreadedMethod()
{

#ifdef ITK_USE_PTHREADS
// ThreadProcessIDType threadId = pthread_self();
#endif

#ifdef ITK_USE_WIN32_THREADS
// ThreadProcessIDType threadId = GetCurrentThread();
#endif

#ifdef ITK_USE_SPROC
// const ThreadProcessIDType threadId = GetCurrentThread()  ??;
#endif

}

} // end of itkMultiThreaderTestHelpers
<|endoftext|>


<commit_before>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ChannelRequest>

#include "TelepathyQt4/_gen/cli-channel-request-body.hpp"
#include "TelepathyQt4/_gen/cli-channel-request.moc.hpp"
#include "TelepathyQt4/_gen/channel-request.moc.hpp"

#include "TelepathyQt4/debug-internal.h"

#include <TelepathyQt4/Account>
#include <TelepathyQt4/PendingFailure>
#include <TelepathyQt4/PendingReady>
#include <TelepathyQt4/PendingVoidMethodCall>

#include <QDateTime>

/**
 * \addtogroup clientsideproxies Client-side proxies
 *
 * Proxy objects representing remote service objects accessed via D-Bus.
 *
 * In addition to providing direct access to methods, signals and properties
 * exported by the remote objects, some of these proxies offer features like
 * automatic inspection of remote object capabilities, property tracking,
 * backwards compatibility helpers for older services and other utilities.
 */

/**
 * \defgroup clientchannelrequest ChannelRequest proxies
 * \ingroup clientsideproxies
 *
 * Proxy objects representing remote Telepathy Channel Requests and their
 * optional interfaces.
 */

namespace Tp
{

struct ChannelRequest::Private
{
    Private(ChannelRequest *parent);
    ~Private();

    static void introspectMain(Private *self);

    // Public object
    ChannelRequest *parent;

    // Instance of generated interface class
    Client::ChannelRequestInterface *baseInterface;

    // Optional interface proxies
    Client::DBus::PropertiesInterface *properties;

    ReadinessHelper *readinessHelper;

    // Introspection
    QStringList interfaces;
    AccountPtr account;
    QDateTime userActionTime;
    QString preferredHandler;
    QualifiedPropertyValueMapList requests;
};

ChannelRequest::Private::Private(ChannelRequest *parent)
    : parent(parent),
      baseInterface(new Client::ChannelRequestInterface(
                    parent->dbusConnection(), parent->busName(),
                    parent->objectPath(), parent)),
      properties(0),
      readinessHelper(parent->readinessHelper())
{
    debug() << "Creating new ChannelRequest:" << parent->objectPath();

    ReadinessHelper::Introspectables introspectables;

    // As ChannelRequest does not have predefined statuses let's simulate one (0)
    ReadinessHelper::Introspectable introspectableCore(
        QSet<uint>() << 0,                                           // makesSenseForStatuses
        Features(),                                                  // dependsOnFeatures
        QStringList(),                                               // dependsOnInterfaces
        (ReadinessHelper::IntrospectFunc) &Private::introspectMain,
        this);
    introspectables[FeatureCore] = introspectableCore;

    readinessHelper->addIntrospectables(introspectables);
    // readinessHelper->becomeReady(Features() << FeatureCore);
}

ChannelRequest::Private::~Private()
{
}

void ChannelRequest::Private::introspectMain(ChannelRequest::Private *self)
{
    if (!self->properties) {
        self->properties = self->parent->propertiesInterface();
        Q_ASSERT(self->properties != 0);
    }

    self->parent->connect(self->baseInterface,
            SIGNAL(Failed(const QString &, const QString &)),
            SIGNAL(failed(const QString &, const QString &)));
    self->parent->connect(self->baseInterface,
            SIGNAL(Succeeded()),
            SIGNAL(succeeded()));

    debug() << "Calling Properties::GetAll(ChannelRequest)";
    QDBusPendingCallWatcher *watcher =
        new QDBusPendingCallWatcher(
                self->properties->GetAll(TELEPATHY_INTERFACE_CHANNEL_REQUEST),
                self->parent);
    // FIXME: This is a Qt bug fixed upstream, should be in the next Qt release.
    //        We should not need to check watcher->isFinished() here, remove the
    //        check when a fixed Qt version is released.
    if (watcher->isFinished()) {
        self->parent->gotMainProperties(watcher);
    } else {
        self->parent->connect(watcher,
                SIGNAL(finished(QDBusPendingCallWatcher*)),
                SLOT(gotMainProperties(QDBusPendingCallWatcher*)));
    }
}

/**
 * \class ChannelRequest
 * \ingroup clientchannelrequest
 * \headerfile <TelepathyQt4/channel-request.h> <TelepathyQt4/ChannelRequest>
 *
 * High-level proxy object for accessing remote Telepathy ChannelRequest objects.
 */

const Feature ChannelRequest::FeatureCore = Feature(ChannelRequest::staticMetaObject.className(), 0, true);

ChannelRequestPtr ChannelRequest::create(const QString &objectPath,
        const QVariantMap &immutableProperties)
{
    return ChannelRequestPtr(new ChannelRequest(objectPath,
                immutableProperties));
}

ChannelRequestPtr ChannelRequest::create(const QDBusConnection &bus,
        const QString &objectPath, const QVariantMap &immutableProperties)
{
    return ChannelRequestPtr(new ChannelRequest(bus, objectPath,
                immutableProperties));
}

ChannelRequest::ChannelRequest(const QString &objectPath,
        const QVariantMap &immutableProperties)
    : StatefulDBusProxy(QDBusConnection::sessionBus(),
            "org.freedesktop.Telepathy.ChannelDispatcher",
            objectPath),
      OptionalInterfaceFactory<ChannelRequest>(this),
      ReadyObject(this, FeatureCore),
      mPriv(new Private(this))
{
    // FIXME: remember the immutableProperties, and use them to reduce the
    // number of D-Bus calls we need to make (but we should make at least
    // one, to check that the channel request does in fact exist)
}

ChannelRequest::ChannelRequest(const QDBusConnection &bus,
        const QString &objectPath, const QVariantMap &immutableProperties)
    : StatefulDBusProxy(bus,
            "org.freedesktop.Telepathy.ChannelDispatcher",
            objectPath),
      OptionalInterfaceFactory<ChannelRequest>(this),
      ReadyObject(this, FeatureCore),
      mPriv(new Private(this))
{
    // FIXME: remember the immutableProperties, and use them to reduce the
    // number of D-Bus calls we need to make (but we should make at least
    // one, to check that the channel request does in fact exist)
}

/**
 * Class destructor.
 */
ChannelRequest::~ChannelRequest()
{
    delete mPriv;
}

QStringList ChannelRequest::interfaces() const
{
    if (!isReady()) {
        warning() << "ChannelRequest::interfaces() used when channel request not ready";
    }
    return mPriv->interfaces;
}

AccountPtr ChannelRequest::account() const
{
    if (!isReady()) {
        warning() << "ChannelRequest::account() used when channel request not ready";
    }
    return mPriv->account;
}

QDateTime ChannelRequest::userActionTime() const
{
    if (!isReady()) {
        warning() << "ChannelRequest::userActionTime() used used channel request not ready";
    }
    return mPriv->userActionTime;
}

QString ChannelRequest::preferredHandler() const
{
    if (!isReady()) {
        warning() << "ChannelRequest::preferredHandler() used when channel request not ready";
    }
    return mPriv->preferredHandler;
}

QualifiedPropertyValueMapList ChannelRequest::requests() const
{
    if (!isReady()) {
        warning() << "ChannelRequest::requests() used when channel request not ready";
    }
    return mPriv->requests;
}

PendingOperation *ChannelRequest::cancel()
{
    return new PendingVoidMethodCall(this, mPriv->baseInterface->Cancel());
}

/**
 * Get the ChannelRequestInterface for this ChannelRequest class. This method is
 * protected since the convenience methods provided by this class should
 * always be used instead of the interface by users of the class.
 *
 * \return A pointer to the existing ChannelRequestInterface for this
 *         ChannelRequest
 */
Client::ChannelRequestInterface *ChannelRequest::baseInterface() const
{
    return mPriv->baseInterface;
}

void ChannelRequest::gotMainProperties(QDBusPendingCallWatcher *watcher)
{
    QDBusPendingReply<QVariantMap> reply = *watcher;
    QVariantMap props;

    if (!reply.isError()) {
        debug() << "Got reply to Properties::GetAll(ChannelRequest)";
        props = reply.value();

        mPriv->interfaces = qdbus_cast<QStringList>(props["Interfaces"]);

        QDBusObjectPath accountObjectPath =
            qdbus_cast<QDBusObjectPath>(props["Account"]);
        mPriv->account = Account::create(
                TELEPATHY_ACCOUNT_MANAGER_BUS_NAME,
                accountObjectPath.path());
        connect(mPriv->account->becomeReady(),
                SIGNAL(finished(Tp::PendingOperation *)),
                SLOT(onAccountReady(Tp::PendingOperation *)));

        // FIXME: Telepathy supports 64-bit time_t, but Qt only does so on
        // ILP64 systems (e.g. sparc64, but not x86_64). If QDateTime
        // gains a fromTimestamp64 method, we should use it instead.
        uint stamp = (uint) qdbus_cast<qlonglong>(props["UserActionTime"]);
        if (stamp != 0) {
            mPriv->userActionTime = QDateTime::fromTime_t(stamp);
        }

        mPriv->preferredHandler = qdbus_cast<QString>(props["PreferredHandler"]);
        mPriv->requests =
            qdbus_cast<QualifiedPropertyValueMapList>(props["Requests"]);
    }
    else {
        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore,
                false, reply.error());
        warning().nospace() << "Properties::GetAll(ChannelRequest) failed with "
            << reply.error().name() << ": " << reply.error().message();
    }
}

void ChannelRequest::onAccountReady(PendingOperation *op)
{
    if (op->isError()) {
        warning() << "Unable to make account ready";
        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false,
                op->errorName(), op->errorMessage());
        return;
    }
    mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
}

} // Tp
<commit_msg>ChannelRequest: Use immutableProperties and do not warn when trying to access properties and not ready.<commit_after>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ChannelRequest>

#include "TelepathyQt4/_gen/cli-channel-request-body.hpp"
#include "TelepathyQt4/_gen/cli-channel-request.moc.hpp"
#include "TelepathyQt4/_gen/channel-request.moc.hpp"

#include "TelepathyQt4/debug-internal.h"

#include <TelepathyQt4/Account>
#include <TelepathyQt4/PendingFailure>
#include <TelepathyQt4/PendingReady>
#include <TelepathyQt4/PendingVoidMethodCall>

#include <QDateTime>

/**
 * \addtogroup clientsideproxies Client-side proxies
 *
 * Proxy objects representing remote service objects accessed via D-Bus.
 *
 * In addition to providing direct access to methods, signals and properties
 * exported by the remote objects, some of these proxies offer features like
 * automatic inspection of remote object capabilities, property tracking,
 * backwards compatibility helpers for older services and other utilities.
 */

/**
 * \defgroup clientchannelrequest ChannelRequest proxies
 * \ingroup clientsideproxies
 *
 * Proxy objects representing remote Telepathy Channel Requests and their
 * optional interfaces.
 */

namespace Tp
{

struct ChannelRequest::Private
{
    Private(ChannelRequest *parent);
    ~Private();

    static void introspectMain(Private *self);

    void extractMainProps(const QVariantMap &props);

    // Public object
    ChannelRequest *parent;

    // Instance of generated interface class
    Client::ChannelRequestInterface *baseInterface;

    // Optional interface proxies
    Client::DBus::PropertiesInterface *properties;

    ReadinessHelper *readinessHelper;

    // Introspection
    QStringList interfaces;
    AccountPtr account;
    QDateTime userActionTime;
    QString preferredHandler;
    QualifiedPropertyValueMapList requests;
};

ChannelRequest::Private::Private(ChannelRequest *parent)
    : parent(parent),
      baseInterface(new Client::ChannelRequestInterface(
                    parent->dbusConnection(), parent->busName(),
                    parent->objectPath(), parent)),
      properties(0),
      readinessHelper(parent->readinessHelper())
{
    debug() << "Creating new ChannelRequest:" << parent->objectPath();

    ReadinessHelper::Introspectables introspectables;

    // As ChannelRequest does not have predefined statuses let's simulate one (0)
    ReadinessHelper::Introspectable introspectableCore(
        QSet<uint>() << 0,                                           // makesSenseForStatuses
        Features(),                                                  // dependsOnFeatures
        QStringList(),                                               // dependsOnInterfaces
        (ReadinessHelper::IntrospectFunc) &Private::introspectMain,
        this);
    introspectables[FeatureCore] = introspectableCore;

    readinessHelper->addIntrospectables(introspectables);
    // readinessHelper->becomeReady(Features() << FeatureCore);
}

ChannelRequest::Private::~Private()
{
}

void ChannelRequest::Private::introspectMain(ChannelRequest::Private *self)
{
    if (!self->properties) {
        self->properties = self->parent->propertiesInterface();
        Q_ASSERT(self->properties != 0);
    }

    self->parent->connect(self->baseInterface,
            SIGNAL(Failed(const QString &, const QString &)),
            SIGNAL(failed(const QString &, const QString &)));
    self->parent->connect(self->baseInterface,
            SIGNAL(Succeeded()),
            SIGNAL(succeeded()));

    debug() << "Calling Properties::GetAll(ChannelRequest)";
    QDBusPendingCallWatcher *watcher =
        new QDBusPendingCallWatcher(
                self->properties->GetAll(TELEPATHY_INTERFACE_CHANNEL_REQUEST),
                self->parent);
    // FIXME: This is a Qt bug fixed upstream, should be in the next Qt release.
    //        We should not need to check watcher->isFinished() here, remove the
    //        check when a fixed Qt version is released.
    if (watcher->isFinished()) {
        self->parent->gotMainProperties(watcher);
    } else {
        self->parent->connect(watcher,
                SIGNAL(finished(QDBusPendingCallWatcher*)),
                SLOT(gotMainProperties(QDBusPendingCallWatcher*)));
    }
}

void ChannelRequest::Private::extractMainProps(const QVariantMap &props)
{
    interfaces = qdbus_cast<QStringList>(props.value("Interfaces"));

    QDBusObjectPath accountObjectPath = qdbus_cast<QDBusObjectPath>(props.value("Account"));
    if (!accountObjectPath.path().isEmpty()) {
        account = Account::create(
                TELEPATHY_ACCOUNT_MANAGER_BUS_NAME,
                accountObjectPath.path());
        parent->connect(account->becomeReady(),
                SIGNAL(finished(Tp::PendingOperation *)),
                SLOT(onAccountReady(Tp::PendingOperation *)));
    }

    // FIXME: Telepathy supports 64-bit time_t, but Qt only does so on
    // ILP64 systems (e.g. sparc64, but not x86_64). If QDateTime
    // gains a fromTimestamp64 method, we should use it instead.
    uint stamp = (uint) qdbus_cast<qlonglong>(props.value("UserActionTime"));
    if (stamp != 0) {
        userActionTime = QDateTime::fromTime_t(stamp);
    }

    preferredHandler = qdbus_cast<QString>(props.value("PreferredHandler"));
    requests = qdbus_cast<QualifiedPropertyValueMapList>(props.value("Requests"));
}

/**
 * \class ChannelRequest
 * \ingroup clientchannelrequest
 * \headerfile <TelepathyQt4/channel-request.h> <TelepathyQt4/ChannelRequest>
 *
 * High-level proxy object for accessing remote Telepathy ChannelRequest objects.
 */

const Feature ChannelRequest::FeatureCore = Feature(ChannelRequest::staticMetaObject.className(), 0, true);

ChannelRequestPtr ChannelRequest::create(const QString &objectPath,
        const QVariantMap &immutableProperties)
{
    return ChannelRequestPtr(new ChannelRequest(objectPath,
                immutableProperties));
}

ChannelRequestPtr ChannelRequest::create(const QDBusConnection &bus,
        const QString &objectPath, const QVariantMap &immutableProperties)
{
    return ChannelRequestPtr(new ChannelRequest(bus, objectPath,
                immutableProperties));
}

ChannelRequest::ChannelRequest(const QString &objectPath,
        const QVariantMap &immutableProperties)
    : StatefulDBusProxy(QDBusConnection::sessionBus(),
            "org.freedesktop.Telepathy.ChannelDispatcher",
            objectPath),
      OptionalInterfaceFactory<ChannelRequest>(this),
      ReadyObject(this, FeatureCore),
      mPriv(new Private(this))
{
    mPriv->extractMainProps(immutableProperties);
}

ChannelRequest::ChannelRequest(const QDBusConnection &bus,
        const QString &objectPath, const QVariantMap &immutableProperties)
    : StatefulDBusProxy(bus,
            "org.freedesktop.Telepathy.ChannelDispatcher",
            objectPath),
      OptionalInterfaceFactory<ChannelRequest>(this),
      ReadyObject(this, FeatureCore),
      mPriv(new Private(this))
{
    mPriv->extractMainProps(immutableProperties);
}

/**
 * Class destructor.
 */
ChannelRequest::~ChannelRequest()
{
    delete mPriv;
}

QStringList ChannelRequest::interfaces() const
{
    return mPriv->interfaces;
}

AccountPtr ChannelRequest::account() const
{
    return mPriv->account;
}

QDateTime ChannelRequest::userActionTime() const
{
    return mPriv->userActionTime;
}

QString ChannelRequest::preferredHandler() const
{
    return mPriv->preferredHandler;
}

QualifiedPropertyValueMapList ChannelRequest::requests() const
{
    return mPriv->requests;
}

PendingOperation *ChannelRequest::cancel()
{
    return new PendingVoidMethodCall(this, mPriv->baseInterface->Cancel());
}

/**
 * Get the ChannelRequestInterface for this ChannelRequest class. This method is
 * protected since the convenience methods provided by this class should
 * always be used instead of the interface by users of the class.
 *
 * \return A pointer to the existing ChannelRequestInterface for this
 *         ChannelRequest
 */
Client::ChannelRequestInterface *ChannelRequest::baseInterface() const
{
    return mPriv->baseInterface;
}

void ChannelRequest::gotMainProperties(QDBusPendingCallWatcher *watcher)
{
    QDBusPendingReply<QVariantMap> reply = *watcher;
    QVariantMap props;

    if (!reply.isError()) {
        debug() << "Got reply to Properties::GetAll(ChannelRequest)";
        props = reply.value();

        mPriv->extractMainProps(props);
    }
    else {
        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore,
                false, reply.error());
        warning().nospace() << "Properties::GetAll(ChannelRequest) failed with "
            << reply.error().name() << ": " << reply.error().message();
    }
}

void ChannelRequest::onAccountReady(PendingOperation *op)
{
    if (op->isError()) {
        warning() << "Unable to make account ready";
        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false,
                op->errorName(), op->errorMessage());
        return;
    }
    mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
}

} // Tp
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2010-2012, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/format.hpp"

#include "OP/OP_Director.h"
#include "PRM/PRM_Default.h"
#include "PRM/PRM_Template.h"

#include "IECore/CompoundObject.h"
#include "IECore/TransformationMatrixData.h"
#include "IECore/VectorTypedData.h"

#include "Convert.h"
#include "ToHoudiniAttribConverter.h"
#include "SOP_InterpolatedCacheReader.h"

using namespace IECore;
using namespace IECoreHoudini;

static PRM_Name parameterNames[] = {
	PRM_Name( "cacheSequence", "Cache Sequence" ),
	PRM_Name( "objectFixes", "Object Prefix/Suffix" ),
	PRM_Name( "attributeFixes", "Attribute Prefix/Suffix" ),
	PRM_Name( "transformAttribute", "Transform Attribute" ),
	PRM_Name( "frameMultiplier", "Frame Multiplier" ),
};

static PRM_Default frameMultiplierDefault( 1 );

PRM_Template SOP_InterpolatedCacheReader::parameters[] = {
	PRM_Template( PRM_FILE, 1, &parameterNames[0] ),
	PRM_Template( PRM_STRING, 2, &parameterNames[1] ),
	PRM_Template( PRM_STRING, 2, &parameterNames[2] ),
	PRM_Template( PRM_STRING, 1, &parameterNames[3] ),
	PRM_Template( PRM_INT, 1, &parameterNames[4], &frameMultiplierDefault ),
	PRM_Template(),
};

SOP_InterpolatedCacheReader::SOP_InterpolatedCacheReader( OP_Network *net, const char *name, OP_Operator *op )
	: SOP_Node( net, name, op ), m_cache( 0 ), m_cacheFileName(), m_frameMultiplier( -1 )
{
	flags().setTimeDep( true );
}

SOP_InterpolatedCacheReader::~SOP_InterpolatedCacheReader()
{
}

OP_Node *SOP_InterpolatedCacheReader::create( OP_Network *net, const char *name, OP_Operator *op )
{
	return new SOP_InterpolatedCacheReader( net, name, op );
}

OP_ERROR SOP_InterpolatedCacheReader::cookMySop( OP_Context &context )
{
	flags().setTimeDep( true );

	if ( lockInputs( context ) >= UT_ERROR_ABORT )
	{
		return error();
	}

	gdp->stashAll();

	float time = context.getTime();
	float frame = context.getFloatFrame();

	UT_String paramVal;

	evalString( paramVal, "cacheSequence", 0, time );
	std::string cacheFileName = paramVal.toStdString();

	evalString( paramVal, "objectFixes", 0, time );
	std::string objectPrefix = paramVal.toStdString();
	evalString( paramVal, "objectFixes", 1, time );
	std::string objectSuffix = paramVal.toStdString();

	evalString( paramVal, "attributeFixes", 0, time );
	std::string attributePrefix = paramVal.toStdString();
	evalString( paramVal, "attributeFixes", 1, time );
	std::string attributeSuffix = paramVal.toStdString();

	evalString( paramVal, "transformAttribute", 0, time );
	std::string transformAttribute = paramVal.toStdString();

	int frameMultiplier = evalInt( "frameMultiplier", 0, time );

	// create the InterpolatedCache
	if ( cacheFileName.compare( m_cacheFileName ) != 0 || frameMultiplier != m_frameMultiplier )
	{
		try
		{
			float fps = OPgetDirector()->getChannelManager()->getSamplesPerSec();
			OversamplesCalculator calc( fps, 1, (int)fps * frameMultiplier );
			m_cache = new InterpolatedCache( cacheFileName, InterpolatedCache::Linear, calc );
		}
		catch ( IECore::InvalidArgumentException e )
		{
			addWarning( SOP_ATTRIBUTE_INVALID, e.what() );
			unlockInputs();
			return error();
		}

		m_cacheFileName = cacheFileName;
		m_frameMultiplier = frameMultiplier;
	}

	if ( !m_cache )
	{
		addWarning( SOP_MESSAGE, "SOP_InterpolatedCacheReader: Cache Sequence not found" );
		unlockInputs();
		return error();
	}

	std::vector<InterpolatedCache::ObjectHandle> objects;
	std::vector<InterpolatedCache::AttributeHandle> attrs;

	try
	{
		m_cache->objects( frame, objects );
	}
	catch ( IECore::Exception e )
	{
		addWarning( SOP_ATTRIBUTE_INVALID, e.what() );
		unlockInputs();
		return error();
	}

	duplicatePointSource( 0, context );

	for ( GA_GroupTable::iterator<GA_ElementGroup> it=gdp->pointGroups().beginTraverse(); !it.atEnd(); ++it )
	{
		GA_PointGroup *group = (GA_PointGroup*)it.group();
		if ( group->getInternal() || group->isEmpty() )
		{
			continue;
		}

		// match GA_PointGroup name to InterpolatedCache::ObjectHandle
		std::string searchName = objectPrefix + group->getName().toStdString() + objectSuffix;
		std::vector<InterpolatedCache::ObjectHandle>::iterator oIt = find( objects.begin(), objects.end(), searchName );
		if ( oIt == objects.end() )
		{
			continue;
		}

		CompoundObjectPtr attributes = 0;

		try
		{
			m_cache->attributes( frame, *oIt, attrs );
			attributes = m_cache->read( frame, *oIt );
		}
		catch ( IECore::Exception e )
		{
			addError( SOP_ATTRIBUTE_INVALID, e.what() );
			unlockInputs();
			return error();
		}

		const CompoundObject::ObjectMap &attributeMap = attributes->members();

		GA_Range pointRange = gdp->getPointRange( group );

		// transfer the InterpolatedCache::Attributes onto the GA_PointGroup
		/// \todo: this does not account for detail, prim, or vertex attribs...
		for ( CompoundObject::ObjectMap::const_iterator aIt=attributeMap.begin(); aIt != attributeMap.end(); aIt++ )
		{
			const Data *data = IECore::runTimeCast<const Data>( aIt->second );
			if ( !data )
			{
				continue;
			}

			ToHoudiniAttribConverterPtr converter = ToHoudiniAttribConverter::create( data );
			if ( !converter )
 			{
 				continue;
 			}

			// strip the prefix/suffix from the GA_Attribute name
			std::string attrName = aIt->first.value();
			size_t prefixLength = attributePrefix.length();
			if ( prefixLength && ( search( attrName.begin(), attrName.begin()+prefixLength, attributePrefix.begin(), attributePrefix.end() ) == attrName.begin() ) )
			{
				attrName.erase( attrName.begin(), attrName.begin() + prefixLength );
			}

			size_t suffixLength = attributeSuffix.length();
			if ( suffixLength && ( search( attrName.end() - suffixLength, attrName.end(), attributeSuffix.begin(), attributeSuffix.end() ) == ( attrName.end() - suffixLength ) ) )
			{
				attrName.erase( attrName.end() - suffixLength, attrName.end() );
			}

			if ( attrName == "P" )
			{
				const V3fVectorData *positions = IECore::runTimeCast<const V3fVectorData>( data );
				if ( !positions )
				{
					continue;
				}

				size_t index = 0;
				size_t entries = pointRange.getEntries();
				const std::vector<Imath::V3f> &pos = positions->readable();

				// Attempting to account for the vertex difference between an IECore::CurvesPrimitive and Houdini curves.
				// As Houdini implicitly triples the endpoints of a curve, a cache generated from a single CurvesPrimitive
				// will have exactly four extra vertices. In this case, we adjust the cache by ignoring the first two and
				// last two V3fs. In all other cases, we report a warning and don't apply the cache to these points.
				if ( pos.size() - 4 == entries )
				{
					index = 2;
				}
				else if ( pos.size() != entries )
				{
					addWarning( SOP_ATTRIBUTE_INVALID, ( boost::format( "Geometry/Cache mismatch: %s contains %d points, while cache expects %d." ) % group->getName().toStdString() % entries % pos.size() ).str().c_str() );
					continue;
				}

				/// \todo: try multi-threading this with a GA_SplittableRange
				for ( GA_Iterator it=pointRange.begin(); !it.atEnd(); ++it, ++index )
				{
					gdp->setPos3( it.getOffset(), IECore::convert<UT_Vector3>( pos[index] ) );
				}

			}
			else
			{
				converter->convert( attrName, gdp, pointRange );
			}
		}

		// if transformAttribute is specified, use to to transform the points
		if ( transformAttribute != "" )
		{
			const TransformationMatrixdData *transform = attributes->member<TransformationMatrixdData>( transformAttribute );
			if ( transform )
			{
				transformPoints<double>( transform->readable(), pointRange );
			}
			else
			{
				const TransformationMatrixfData *transform = attributes->member<TransformationMatrixfData>( transformAttribute );
				if ( transform )
				{
					transformPoints<float>( transform->readable(), pointRange );
				}
			}
		}
	}

	unlockInputs();
	return error();
}

template<typename T>
void SOP_InterpolatedCacheReader::transformPoints( const IECore::TransformationMatrix<T> &transform, const GA_Range &range )
{
	UT_Matrix4T<T> matrix = IECore::convert<UT_Matrix4T<T> >( transform.transform() );

	/// \todo: try multi-threading this with a GA_SplittableRange
	for ( GA_Iterator it=range.begin(); !it.atEnd(); ++it )
	{
		gdp->setPos3( it.getOffset(), gdp->getPos3( it.getOffset() ) * matrix );
	}
}
<commit_msg>added todos<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2010-2012, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/format.hpp"

#include "OP/OP_Director.h"
#include "PRM/PRM_Default.h"
#include "PRM/PRM_Template.h"

#include "IECore/CompoundObject.h"
#include "IECore/TransformationMatrixData.h"
#include "IECore/VectorTypedData.h"

#include "Convert.h"
#include "ToHoudiniAttribConverter.h"
#include "SOP_InterpolatedCacheReader.h"

using namespace IECore;
using namespace IECoreHoudini;

static PRM_Name parameterNames[] = {
	PRM_Name( "cacheSequence", "Cache Sequence" ),
	PRM_Name( "objectFixes", "Object Prefix/Suffix" ),
	PRM_Name( "attributeFixes", "Attribute Prefix/Suffix" ),
	PRM_Name( "transformAttribute", "Transform Attribute" ),
	PRM_Name( "frameMultiplier", "Frame Multiplier" ),
};

static PRM_Default frameMultiplierDefault( 1 );

PRM_Template SOP_InterpolatedCacheReader::parameters[] = {
	PRM_Template( PRM_FILE, 1, &parameterNames[0] ),
	PRM_Template( PRM_STRING, 2, &parameterNames[1] ),
	PRM_Template( PRM_STRING, 2, &parameterNames[2] ),
	PRM_Template( PRM_STRING, 1, &parameterNames[3] ),
	PRM_Template( PRM_INT, 1, &parameterNames[4], &frameMultiplierDefault ),
	PRM_Template(),
};

SOP_InterpolatedCacheReader::SOP_InterpolatedCacheReader( OP_Network *net, const char *name, OP_Operator *op )
	: SOP_Node( net, name, op ), m_cache( 0 ), m_cacheFileName(), m_frameMultiplier( -1 )
{
	flags().setTimeDep( true );
}

SOP_InterpolatedCacheReader::~SOP_InterpolatedCacheReader()
{
}

OP_Node *SOP_InterpolatedCacheReader::create( OP_Network *net, const char *name, OP_Operator *op )
{
	return new SOP_InterpolatedCacheReader( net, name, op );
}

OP_ERROR SOP_InterpolatedCacheReader::cookMySop( OP_Context &context )
{
	flags().setTimeDep( true );

	if ( lockInputs( context ) >= UT_ERROR_ABORT )
	{
		return error();
	}

	gdp->stashAll();

	float time = context.getTime();
	float frame = context.getFloatFrame();

	UT_String paramVal;

	evalString( paramVal, "cacheSequence", 0, time );
	std::string cacheFileName = paramVal.toStdString();

	evalString( paramVal, "objectFixes", 0, time );
	std::string objectPrefix = paramVal.toStdString();
	evalString( paramVal, "objectFixes", 1, time );
	std::string objectSuffix = paramVal.toStdString();

	evalString( paramVal, "attributeFixes", 0, time );
	std::string attributePrefix = paramVal.toStdString();
	evalString( paramVal, "attributeFixes", 1, time );
	std::string attributeSuffix = paramVal.toStdString();

	evalString( paramVal, "transformAttribute", 0, time );
	std::string transformAttribute = paramVal.toStdString();

	int frameMultiplier = evalInt( "frameMultiplier", 0, time );

	// create the InterpolatedCache
	if ( cacheFileName.compare( m_cacheFileName ) != 0 || frameMultiplier != m_frameMultiplier )
	{
		try
		{
			float fps = OPgetDirector()->getChannelManager()->getSamplesPerSec();
			/// \todo: expose samplesPerFrame as a parameter
			OversamplesCalculator calc( fps, 1, (int)fps * frameMultiplier );
			/// \todo: expose interpolation type as a parameter
			m_cache = new InterpolatedCache( cacheFileName, InterpolatedCache::Linear, calc );
		}
		catch ( IECore::InvalidArgumentException e )
		{
			addWarning( SOP_ATTRIBUTE_INVALID, e.what() );
			unlockInputs();
			return error();
		}

		m_cacheFileName = cacheFileName;
		m_frameMultiplier = frameMultiplier;
	}

	if ( !m_cache )
	{
		addWarning( SOP_MESSAGE, "SOP_InterpolatedCacheReader: Cache Sequence not found" );
		unlockInputs();
		return error();
	}

	std::vector<InterpolatedCache::ObjectHandle> objects;
	std::vector<InterpolatedCache::AttributeHandle> attrs;

	try
	{
		m_cache->objects( frame, objects );
	}
	catch ( IECore::Exception e )
	{
		addWarning( SOP_ATTRIBUTE_INVALID, e.what() );
		unlockInputs();
		return error();
	}

	duplicatePointSource( 0, context );

	for ( GA_GroupTable::iterator<GA_ElementGroup> it=gdp->pointGroups().beginTraverse(); !it.atEnd(); ++it )
	{
		GA_PointGroup *group = (GA_PointGroup*)it.group();
		if ( group->getInternal() || group->isEmpty() )
		{
			continue;
		}

		// match GA_PointGroup name to InterpolatedCache::ObjectHandle
		std::string searchName = objectPrefix + group->getName().toStdString() + objectSuffix;
		std::vector<InterpolatedCache::ObjectHandle>::iterator oIt = find( objects.begin(), objects.end(), searchName );
		if ( oIt == objects.end() )
		{
			continue;
		}

		CompoundObjectPtr attributes = 0;

		try
		{
			m_cache->attributes( frame, *oIt, attrs );
			attributes = m_cache->read( frame, *oIt );
		}
		catch ( IECore::Exception e )
		{
			addError( SOP_ATTRIBUTE_INVALID, e.what() );
			unlockInputs();
			return error();
		}

		const CompoundObject::ObjectMap &attributeMap = attributes->members();

		GA_Range pointRange = gdp->getPointRange( group );

		// transfer the InterpolatedCache::Attributes onto the GA_PointGroup
		/// \todo: this does not account for detail, prim, or vertex attribs...
		for ( CompoundObject::ObjectMap::const_iterator aIt=attributeMap.begin(); aIt != attributeMap.end(); aIt++ )
		{
			const Data *data = IECore::runTimeCast<const Data>( aIt->second );
			if ( !data )
			{
				continue;
			}

			ToHoudiniAttribConverterPtr converter = ToHoudiniAttribConverter::create( data );
			if ( !converter )
 			{
 				continue;
 			}

			// strip the prefix/suffix from the GA_Attribute name
			std::string attrName = aIt->first.value();
			size_t prefixLength = attributePrefix.length();
			if ( prefixLength && ( search( attrName.begin(), attrName.begin()+prefixLength, attributePrefix.begin(), attributePrefix.end() ) == attrName.begin() ) )
			{
				attrName.erase( attrName.begin(), attrName.begin() + prefixLength );
			}

			size_t suffixLength = attributeSuffix.length();
			if ( suffixLength && ( search( attrName.end() - suffixLength, attrName.end(), attributeSuffix.begin(), attributeSuffix.end() ) == ( attrName.end() - suffixLength ) ) )
			{
				attrName.erase( attrName.end() - suffixLength, attrName.end() );
			}

			if ( attrName == "P" )
			{
				const V3fVectorData *positions = IECore::runTimeCast<const V3fVectorData>( data );
				if ( !positions )
				{
					continue;
				}

				size_t index = 0;
				size_t entries = pointRange.getEntries();
				const std::vector<Imath::V3f> &pos = positions->readable();

				// Attempting to account for the vertex difference between an IECore::CurvesPrimitive and Houdini curves.
				// As Houdini implicitly triples the endpoints of a curve, a cache generated from a single CurvesPrimitive
				// will have exactly four extra vertices. In this case, we adjust the cache by ignoring the first two and
				// last two V3fs. In all other cases, we report a warning and don't apply the cache to these points.
				if ( pos.size() - 4 == entries )
				{
					index = 2;
				}
				else if ( pos.size() != entries )
				{
					addWarning( SOP_ATTRIBUTE_INVALID, ( boost::format( "Geometry/Cache mismatch: %s contains %d points, while cache expects %d." ) % group->getName().toStdString() % entries % pos.size() ).str().c_str() );
					continue;
				}

				/// \todo: try multi-threading this with a GA_SplittableRange
				for ( GA_Iterator it=pointRange.begin(); !it.atEnd(); ++it, ++index )
				{
					gdp->setPos3( it.getOffset(), IECore::convert<UT_Vector3>( pos[index] ) );
				}

			}
			else
			{
				converter->convert( attrName, gdp, pointRange );
			}
		}

		// if transformAttribute is specified, use to to transform the points
		if ( transformAttribute != "" )
		{
			const TransformationMatrixdData *transform = attributes->member<TransformationMatrixdData>( transformAttribute );
			if ( transform )
			{
				transformPoints<double>( transform->readable(), pointRange );
			}
			else
			{
				const TransformationMatrixfData *transform = attributes->member<TransformationMatrixfData>( transformAttribute );
				if ( transform )
				{
					transformPoints<float>( transform->readable(), pointRange );
				}
			}
		}
	}

	unlockInputs();
	return error();
}

template<typename T>
void SOP_InterpolatedCacheReader::transformPoints( const IECore::TransformationMatrix<T> &transform, const GA_Range &range )
{
	UT_Matrix4T<T> matrix = IECore::convert<UT_Matrix4T<T> >( transform.transform() );

	/// \todo: try multi-threading this with a GA_SplittableRange
	for ( GA_Iterator it=range.begin(); !it.atEnd(); ++it )
	{
		gdp->setPos3( it.getOffset(), gdp->getPos3( it.getOffset() ) * matrix );
	}
}
<|endoftext|>


<commit_before>//
// Glue code between libMini and its file format support
//
// Copyright (c) 2008 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include <mini/convbase.h>

void InitMiniConvHook(int iJpegQuality)
{
	// specify conversion parameters
	static convbase::MINI_CONVERSION_PARAMS conversion_params;
	conversion_params.jpeg_quality = iJpegQuality; // jpeg quality in percent
	conversion_params.usegreycstoration = false; // use greycstoration for image denoising
	conversion_params.greyc_p=0.8f; // greycstoration sharpness, useful range=[0.7-0.9]
	conversion_params.greyc_a=0.4f; // greycstoration anisotropy, useful range=[0.1-0.5]

	// register libMini conversion hook (JPEG/PNG)
	databuf::setconversion(convbase::conversionhook,&conversion_params);
}

<commit_msg>fix tiny compiler warning<commit_after>//
// Glue code between libMini and its file format support
//
// Copyright (c) 2008 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include <mini/convbase.h>

void InitMiniConvHook(int iJpegQuality)
{
	// specify conversion parameters
	static convbase::MINI_CONVERSION_PARAMS conversion_params;
	conversion_params.jpeg_quality = (float) iJpegQuality; // jpeg quality in percent
	conversion_params.usegreycstoration = false; // use greycstoration for image denoising
	conversion_params.greyc_p=0.8f; // greycstoration sharpness, useful range=[0.7-0.9]
	conversion_params.greyc_a=0.4f; // greycstoration anisotropy, useful range=[0.1-0.5]

	// register libMini conversion hook (JPEG/PNG)
	databuf::setconversion(convbase::conversionhook,&conversion_params);
}

<|endoftext|>


<commit_before>//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <stdio.h>
#include <string.h>
#include "../../test_common/harness/testHarness.h"
#include "../../test_common/harness/typeWrappers.h"

#include <vector>

#include "procs.h"
#include "utils.h"
#include <time.h>

extern int gWimpyMode;

#ifdef CL_VERSION_2_0

static const char* enqueue_block_first_kernel[] =
{
    NL, "void block_fn(uint num, __global int* res)"
    NL, "{"
    NL, "    size_t tid = get_global_id(0);"
    NL, ""
    NL, "    for(int i = 1 ; i < tid ; i++)"
    NL, "    {"
    NL, "      for(int j = 0 ; j < num ; j++)"
    NL, "        atomic_add(res+tid, (int)sqrt((float)i*i) / i);"
    NL, "    }"
    NL, "}"
    NL, ""
    NL, "kernel void enqueue_block_first_kernel(uint num, __global int* res)"
    NL, "{"
    NL, "  void (^kernelBlock)(void) = ^{ block_fn(num, res); };"
    NL, ""
    NL, "  ndrange_t ndrange = ndrange_1D(num, 1);"
    NL, ""
    NL, "  int enq_res = enqueue_kernel(get_default_queue(), CLK_ENQUEUE_FLAGS_NO_WAIT, ndrange, kernelBlock);"
    NL, "  if(enq_res != CLK_SUCCESS) { res[0] = -1; return; }"
    NL, ""
    NL, "}"
    NL
};

static const char* enqueue_block_second_kernel[] =
{
    NL, "void block_fn(uint num, __global int* res)"
    NL, "{"
    NL, "    for(int i = 2 ; i < num ; i++)"
    NL, "    {"
    NL, "      res[i] = res[i]/num - (i-1);"
    NL, "    }"
    NL, "}"
    NL, ""
    NL, "kernel void enqueue_block_second_kernel(uint num, __global int* res)"
    NL, "{"
    NL, "  void (^kernelBlock)(void) = ^{ block_fn(num, res); };"
    NL, ""
    NL, "  ndrange_t ndrange = ndrange_1D(1);"
    NL, ""
    NL, "  int enq_res = enqueue_kernel(get_default_queue(), CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange, kernelBlock);"
    NL, "  if(enq_res != CLK_SUCCESS) { res[0] = -1; return; }"
    NL, ""
    NL, "}"
    NL
};

static int check_kernel_results(cl_int* results, cl_int len)
{
    for(cl_int i = 0; i < len; ++i)
    {
        if(results[i] != 0) return i;
    }
    return -1;
}

/*
    Test checks kernel block execution order in case of two different kernels with enqueue block submitted to one ordered host queue.
*/
int test_host_queue_order(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
    cl_int k, err_ret, res = 0;
    clCommandQueueWrapper dev_queue;
    cl_int kernel_results[MAX_GWS] = {0};

    size_t ret_len;
    cl_uint max_queues = 1;
    cl_uint maxQueueSize = 0;
    err_ret = clGetDeviceInfo(device, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE, sizeof(maxQueueSize), &maxQueueSize, 0);
    test_error(err_ret, "clGetDeviceInfo(CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE) failed");

    err_ret = clGetDeviceInfo(device, CL_DEVICE_MAX_ON_DEVICE_QUEUES, sizeof(max_queues), &max_queues, &ret_len);
    test_error(err_ret, "clGetDeviceInfo(CL_DEVICE_MAX_ON_DEVICE_QUEUES) failed");

    size_t max_local_size = 1;
    err_ret = clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(max_local_size), &max_local_size, &ret_len);
    test_error(err_ret, "clGetDeviceInfo(CL_DEVICE_MAX_WORK_GROUP_SIZE) failed");

    cl_queue_properties queue_prop_def[] =
    {
        CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE|CL_QUEUE_ON_DEVICE|CL_QUEUE_ON_DEVICE_DEFAULT,
        CL_QUEUE_SIZE, maxQueueSize,
        0
    };

    dev_queue = clCreateCommandQueueWithProperties(context, device, queue_prop_def, &err_ret);
    test_error(err_ret, "clCreateCommandQueueWithProperties(CL_QUEUE_DEVICE|CL_QUEUE_DEFAULT) failed");

    cl_int status;
    size_t size = 1;
    cl_int result[MAX_GWS] = { 0 };
    cl_uint num = arr_size(result);
    if( gWimpyMode )
    {
        num = MAX(num / 16, 4);
    }

    clMemWrapper res_mem;
    clProgramWrapper program1, program2;
    clKernelWrapper kernel1, kernel2;

    cl_event kernel_event;

    err_ret = create_single_kernel_helper_with_build_options(context, &program1, &kernel1,  arr_size(enqueue_block_first_kernel), enqueue_block_first_kernel, "enqueue_block_first_kernel", "-cl-std=CL2.0");
    if(check_error(err_ret, "Create single kernel failed")) return -1;

    err_ret = create_single_kernel_helper_with_build_options(context, &program2, &kernel2, arr_size(enqueue_block_second_kernel), enqueue_block_second_kernel, "enqueue_block_second_kernel", "-cl-std=CL2.0");
    if(check_error(err_ret, "Create single kernel failed")) return -1;

    res_mem = clCreateBuffer(context, CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR, sizeof(kernel_results), kernel_results, &err_ret);
    test_error(err_ret, "clCreateBuffer() failed");

    // Enqueue first kernel
    err_ret = clSetKernelArg(kernel1, 0, sizeof(num), &num);
    test_error(err_ret, "clSetKernelArg(0) failed");
    err_ret = clSetKernelArg(kernel1, 1, sizeof(cl_mem), &res_mem);
    test_error(err_ret, "clSetKernelArg(1) failed");

    cl_event event1 = clCreateUserEvent(context, &err_ret);
    if(check_error(err_ret, "Create user event failed")) return -1;

    err_ret = clEnqueueNDRangeKernel(queue, kernel1, 1, NULL, &size, &size, 1, &event1, NULL);
    test_error(err_ret, "clEnqueueNDRangeKernel('enqueue_block_first_kernel') failed");

    // Enqueue second kernel
    err_ret = clSetKernelArg(kernel2, 0, sizeof(num), &num);
    test_error(err_ret, "clSetKernelArg(0) failed");
    err_ret = clSetKernelArg(kernel2, 1, sizeof(cl_mem), &res_mem);
    test_error(err_ret, "clSetKernelArg(1) failed");

    err_ret = clEnqueueNDRangeKernel(queue, kernel2, 1, NULL, &size, &size, 0, NULL, &kernel_event);
    test_error(err_ret, "clEnqueueNDRangeKernel('enqueue_block_second_kernel') failed");

    //Triger execution of first kernel
    err_ret = clSetUserEventStatus(event1, CL_COMPLETE);
    test_error(err_ret, "clSetUserEventStatus() failed");

    // Collect resulsts
    err_ret = clEnqueueReadBuffer(queue, res_mem, CL_TRUE, 0, sizeof(result), result, 0, NULL, NULL);
    test_error(err_ret, "clEnqueueReadBuffer() failed");

    err_ret = clGetEventInfo(kernel_event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(status), &status, &ret_len);
    test_error(err_ret, "clGetEventInfo() failed");

    if(check_error(status, "Kernel execution status %d", status)) return status;

    if((k = check_kernel_results(result, num)) >= 0 && check_error(-1, "'%s' results validation failed: [%d] returned %d expected 0", "test_host_queue_order", k, result[k])) res = -1;

    return res;
}

#endif

<commit_msg>Bugfix for Khronos Bug 16242. (#261)<commit_after>//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <stdio.h>
#include <string.h>
#include "../../test_common/harness/testHarness.h"
#include "../../test_common/harness/typeWrappers.h"

#include <vector>

#include "procs.h"
#include "utils.h"
#include <time.h>

extern int gWimpyMode;

#ifdef CL_VERSION_2_0

static const char* enqueue_block_first_kernel[] =
{
    NL, "void block_fn(uint num, __global int* res)"
    NL, "{"
    NL, "    size_t tid = get_global_id(0);"
    NL, ""
    NL, "    for(int i = 1 ; i < tid ; i++)"
    NL, "    {"
    NL, "      for(int j = 0 ; j < num ; j++)"
    NL, "        atomic_add(res+tid, convert_int_rte(sqrt((float)i*i) / i));"
    NL, "    }"
    NL, "}"
    NL, ""
    NL, "kernel void enqueue_block_first_kernel(uint num, __global int* res)"
    NL, "{"
    NL, "  void (^kernelBlock)(void) = ^{ block_fn(num, res); };"
    NL, ""
    NL, "  ndrange_t ndrange = ndrange_1D(num, 1);"
    NL, ""
    NL, "  int enq_res = enqueue_kernel(get_default_queue(), CLK_ENQUEUE_FLAGS_NO_WAIT, ndrange, kernelBlock);"
    NL, "  if(enq_res != CLK_SUCCESS) { res[0] = -1; return; }"
    NL, ""
    NL, "}"
    NL
};

static const char* enqueue_block_second_kernel[] =
{
    NL, "void block_fn(uint num, __global int* res)"
    NL, "{"
    NL, "    for(int i = 2 ; i < num ; i++)"
    NL, "    {"
    NL, "      res[i] = res[i]/num - (i-1);"
    NL, "    }"
    NL, "}"
    NL, ""
    NL, "kernel void enqueue_block_second_kernel(uint num, __global int* res)"
    NL, "{"
    NL, "  void (^kernelBlock)(void) = ^{ block_fn(num, res); };"
    NL, ""
    NL, "  ndrange_t ndrange = ndrange_1D(1);"
    NL, ""
    NL, "  int enq_res = enqueue_kernel(get_default_queue(), CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange, kernelBlock);"
    NL, "  if(enq_res != CLK_SUCCESS) { res[0] = -1; return; }"
    NL, ""
    NL, "}"
    NL
};

static int check_kernel_results(cl_int* results, cl_int len)
{
    for(cl_int i = 0; i < len; ++i)
    {
        if(results[i] != 0) return i;
    }
    return -1;
}

/*
    Test checks kernel block execution order in case of two different kernels with enqueue block submitted to one ordered host queue.
*/
int test_host_queue_order(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
    cl_int k, err_ret, res = 0;
    clCommandQueueWrapper dev_queue;
    cl_int kernel_results[MAX_GWS] = {0};

    size_t ret_len;
    cl_uint max_queues = 1;
    cl_uint maxQueueSize = 0;
    err_ret = clGetDeviceInfo(device, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE, sizeof(maxQueueSize), &maxQueueSize, 0);
    test_error(err_ret, "clGetDeviceInfo(CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE) failed");

    err_ret = clGetDeviceInfo(device, CL_DEVICE_MAX_ON_DEVICE_QUEUES, sizeof(max_queues), &max_queues, &ret_len);
    test_error(err_ret, "clGetDeviceInfo(CL_DEVICE_MAX_ON_DEVICE_QUEUES) failed");

    size_t max_local_size = 1;
    err_ret = clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(max_local_size), &max_local_size, &ret_len);
    test_error(err_ret, "clGetDeviceInfo(CL_DEVICE_MAX_WORK_GROUP_SIZE) failed");

    cl_queue_properties queue_prop_def[] =
    {
        CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE|CL_QUEUE_ON_DEVICE|CL_QUEUE_ON_DEVICE_DEFAULT,
        CL_QUEUE_SIZE, maxQueueSize,
        0
    };

    dev_queue = clCreateCommandQueueWithProperties(context, device, queue_prop_def, &err_ret);
    test_error(err_ret, "clCreateCommandQueueWithProperties(CL_QUEUE_DEVICE|CL_QUEUE_DEFAULT) failed");

    cl_int status;
    size_t size = 1;
    cl_int result[MAX_GWS] = { 0 };
    cl_uint num = arr_size(result);
    if( gWimpyMode )
    {
        num = MAX(num / 16, 4);
    }

    clMemWrapper res_mem;
    clProgramWrapper program1, program2;
    clKernelWrapper kernel1, kernel2;

    cl_event kernel_event;

    err_ret = create_single_kernel_helper_with_build_options(context, &program1, &kernel1,  arr_size(enqueue_block_first_kernel), enqueue_block_first_kernel, "enqueue_block_first_kernel", "-cl-std=CL2.0");
    if(check_error(err_ret, "Create single kernel failed")) return -1;

    err_ret = create_single_kernel_helper_with_build_options(context, &program2, &kernel2, arr_size(enqueue_block_second_kernel), enqueue_block_second_kernel, "enqueue_block_second_kernel", "-cl-std=CL2.0");
    if(check_error(err_ret, "Create single kernel failed")) return -1;

    res_mem = clCreateBuffer(context, CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR, sizeof(kernel_results), kernel_results, &err_ret);
    test_error(err_ret, "clCreateBuffer() failed");

    // Enqueue first kernel
    err_ret = clSetKernelArg(kernel1, 0, sizeof(num), &num);
    test_error(err_ret, "clSetKernelArg(0) failed");
    err_ret = clSetKernelArg(kernel1, 1, sizeof(cl_mem), &res_mem);
    test_error(err_ret, "clSetKernelArg(1) failed");

    cl_event event1 = clCreateUserEvent(context, &err_ret);
    if(check_error(err_ret, "Create user event failed")) return -1;

    err_ret = clEnqueueNDRangeKernel(queue, kernel1, 1, NULL, &size, &size, 1, &event1, NULL);
    test_error(err_ret, "clEnqueueNDRangeKernel('enqueue_block_first_kernel') failed");

    // Enqueue second kernel
    err_ret = clSetKernelArg(kernel2, 0, sizeof(num), &num);
    test_error(err_ret, "clSetKernelArg(0) failed");
    err_ret = clSetKernelArg(kernel2, 1, sizeof(cl_mem), &res_mem);
    test_error(err_ret, "clSetKernelArg(1) failed");

    err_ret = clEnqueueNDRangeKernel(queue, kernel2, 1, NULL, &size, &size, 0, NULL, &kernel_event);
    test_error(err_ret, "clEnqueueNDRangeKernel('enqueue_block_second_kernel') failed");

    //Triger execution of first kernel
    err_ret = clSetUserEventStatus(event1, CL_COMPLETE);
    test_error(err_ret, "clSetUserEventStatus() failed");

    // Collect resulsts
    err_ret = clEnqueueReadBuffer(queue, res_mem, CL_TRUE, 0, sizeof(result), result, 0, NULL, NULL);
    test_error(err_ret, "clEnqueueReadBuffer() failed");

    err_ret = clGetEventInfo(kernel_event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(status), &status, &ret_len);
    test_error(err_ret, "clGetEventInfo() failed");

    if(check_error(status, "Kernel execution status %d", status)) return status;

    if((k = check_kernel_results(result, num)) >= 0 && check_error(-1, "'%s' results validation failed: [%d] returned %d expected 0", "test_host_queue_order", k, result[k])) res = -1;

    return res;
}

#endif

<|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 "app/resource_bundle.h"

#include "app/gfx/font.h"
#include "base/gfx/png_decoder.h"
#include "base/logging.h"
#include "base/string_piece.h"
#include "net/base/file_stream.h"
#include "net/base/net_errors.h"
#include "third_party/skia/include/core/SkBitmap.h"

ResourceBundle* ResourceBundle::g_shared_instance_ = NULL;

/* static */
// TODO(glen): Finish moving these into theme provider (dialogs still
//    depend on these colors).
const SkColor ResourceBundle::frame_color =
     SkColorSetRGB(77, 139, 217);
const SkColor ResourceBundle::frame_color_inactive =
     SkColorSetRGB(184, 209, 240);
const SkColor ResourceBundle::frame_color_incognito =
     SkColorSetRGB(83, 106, 139);
const SkColor ResourceBundle::frame_color_incognito_inactive =
     SkColorSetRGB(126, 139, 156);
const SkColor ResourceBundle::toolbar_color =
     SkColorSetRGB(210, 225, 246);
const SkColor ResourceBundle::toolbar_separator_color =
     SkColorSetRGB(182, 186, 192);

/* static */
void ResourceBundle::InitSharedInstance(const std::wstring& pref_locale) {
  DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice";
  g_shared_instance_ = new ResourceBundle();

  g_shared_instance_->LoadResources(pref_locale);
}

/* static */
void ResourceBundle::CleanupSharedInstance() {
  if (g_shared_instance_) {
    delete g_shared_instance_;
    g_shared_instance_ = NULL;
  }
}

/* static */
ResourceBundle& ResourceBundle::GetSharedInstance() {
  // Must call InitSharedInstance before this function.
  CHECK(g_shared_instance_ != NULL);
  return *g_shared_instance_;
}

ResourceBundle::ResourceBundle()
    : resources_data_(NULL),
      locale_resources_data_(NULL),
      theme_data_(NULL) {
}

void ResourceBundle::FreeImages() {
  for (SkImageMap::iterator i = skia_images_.begin();
       i != skia_images_.end(); i++) {
    delete i->second;
  }
  skia_images_.clear();
}

/* static */
SkBitmap* ResourceBundle::LoadBitmap(DataHandle data_handle, int resource_id) {
  std::vector<unsigned char> raw_data, png_data;
  bool success = false;

  if (!success)
    success = LoadResourceBytes(data_handle, resource_id, &raw_data);
  if (!success)
    return NULL;

  // Decode the PNG.
  int image_width;
  int image_height;
  if (!PNGDecoder::Decode(&raw_data.front(), raw_data.size(),
                          PNGDecoder::FORMAT_BGRA,
                          &png_data, &image_width, &image_height)) {
    NOTREACHED() << "Unable to decode image resource " << resource_id;
    return NULL;
  }

  return PNGDecoder::CreateSkBitmapFromBGRAFormat(png_data,
                                                  image_width,
                                                  image_height);
}

std::string ResourceBundle::GetDataResource(int resource_id) {
  return GetRawDataResource(resource_id).as_string();
}

bool ResourceBundle::LoadImageResourceBytes(int resource_id,
                                            std::vector<unsigned char>* bytes) {
  return LoadResourceBytes(theme_data_, resource_id, bytes);
}

bool ResourceBundle::LoadDataResourceBytes(int resource_id,
                                           std::vector<unsigned char>* bytes) {
  return LoadResourceBytes(resources_data_, resource_id, bytes);
}

SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) {
  // Check to see if we already have the Skia image in the cache.
  {
    AutoLock lock_scope(lock_);
    SkImageMap::const_iterator found = skia_images_.find(resource_id);
    if (found != skia_images_.end())
      return found->second;
  }

  scoped_ptr<SkBitmap> bitmap;

  if (theme_data_)
    bitmap.reset(LoadBitmap(theme_data_, resource_id));

  // If we did not find the bitmap in the theme DLL, try the current one.
  if (!bitmap.get())
    bitmap.reset(LoadBitmap(resources_data_, resource_id));

  // We loaded successfully.  Cache the Skia version of the bitmap.
  if (bitmap.get()) {
    AutoLock lock_scope(lock_);

    // Another thread raced us, and has already cached the skia image.
    if (skia_images_.count(resource_id))
      return skia_images_[resource_id];

    skia_images_[resource_id] = bitmap.get();
    return bitmap.release();
  }

  // We failed to retrieve the bitmap, show a debugging red square.
  {
    LOG(WARNING) << "Unable to load bitmap with id " << resource_id;
    NOTREACHED();  // Want to assert in debug mode.

    AutoLock lock_scope(lock_);  // Guard empty_bitmap initialization.

    static SkBitmap* empty_bitmap = NULL;
    if (!empty_bitmap) {
      // The placeholder bitmap is bright red so people notice the problem.
      // This bitmap will be leaked, but this code should never be hit.
      empty_bitmap = new SkBitmap();
      empty_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
      empty_bitmap->allocPixels();
      empty_bitmap->eraseARGB(255, 255, 0, 0);
    }
    return empty_bitmap;
  }
}

void ResourceBundle::LoadFontsIfNecessary() {
  AutoLock lock_scope(lock_);
  if (!base_font_.get()) {
    base_font_.reset(new gfx::Font());

    small_font_.reset(new gfx::Font());
    *small_font_ = base_font_->DeriveFont(-2);

    medium_font_.reset(new gfx::Font());
    *medium_font_ = base_font_->DeriveFont(3);

    medium_bold_font_.reset(new gfx::Font());
    *medium_bold_font_ =
        base_font_->DeriveFont(3, base_font_->style() | gfx::Font::BOLD);

    large_font_.reset(new gfx::Font());
    *large_font_ = base_font_->DeriveFont(8);
  }
}

gfx::Font ResourceBundle::GetFont(FontStyle style) {
  LoadFontsIfNecessary();
  switch(style) {
    case SmallFont:
      return *small_font_;
    case MediumFont:
      return *medium_font_;
    case MediumBoldFont:
      return *medium_bold_font_;
    case LargeFont:
      return *large_font_;
    default:
      return *base_font_;
  }
}
<commit_msg>Use a less gigantor base font for TOOLKIT_VIEWS to better match the aesthetic of the bitmap-based UI.<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 "app/resource_bundle.h"

#include "app/gfx/font.h"
#include "base/gfx/png_decoder.h"
#include "base/logging.h"
#include "base/string_piece.h"
#include "net/base/file_stream.h"
#include "net/base/net_errors.h"
#include "third_party/skia/include/core/SkBitmap.h"

ResourceBundle* ResourceBundle::g_shared_instance_ = NULL;

/* static */
// TODO(glen): Finish moving these into theme provider (dialogs still
//    depend on these colors).
const SkColor ResourceBundle::frame_color =
     SkColorSetRGB(77, 139, 217);
const SkColor ResourceBundle::frame_color_inactive =
     SkColorSetRGB(184, 209, 240);
const SkColor ResourceBundle::frame_color_incognito =
     SkColorSetRGB(83, 106, 139);
const SkColor ResourceBundle::frame_color_incognito_inactive =
     SkColorSetRGB(126, 139, 156);
const SkColor ResourceBundle::toolbar_color =
     SkColorSetRGB(210, 225, 246);
const SkColor ResourceBundle::toolbar_separator_color =
     SkColorSetRGB(182, 186, 192);

/* static */
void ResourceBundle::InitSharedInstance(const std::wstring& pref_locale) {
  DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice";
  g_shared_instance_ = new ResourceBundle();

  g_shared_instance_->LoadResources(pref_locale);
}

/* static */
void ResourceBundle::CleanupSharedInstance() {
  if (g_shared_instance_) {
    delete g_shared_instance_;
    g_shared_instance_ = NULL;
  }
}

/* static */
ResourceBundle& ResourceBundle::GetSharedInstance() {
  // Must call InitSharedInstance before this function.
  CHECK(g_shared_instance_ != NULL);
  return *g_shared_instance_;
}

ResourceBundle::ResourceBundle()
    : resources_data_(NULL),
      locale_resources_data_(NULL),
      theme_data_(NULL) {
}

void ResourceBundle::FreeImages() {
  for (SkImageMap::iterator i = skia_images_.begin();
       i != skia_images_.end(); i++) {
    delete i->second;
  }
  skia_images_.clear();
}

/* static */
SkBitmap* ResourceBundle::LoadBitmap(DataHandle data_handle, int resource_id) {
  std::vector<unsigned char> raw_data, png_data;
  bool success = false;

  if (!success)
    success = LoadResourceBytes(data_handle, resource_id, &raw_data);
  if (!success)
    return NULL;

  // Decode the PNG.
  int image_width;
  int image_height;
  if (!PNGDecoder::Decode(&raw_data.front(), raw_data.size(),
                          PNGDecoder::FORMAT_BGRA,
                          &png_data, &image_width, &image_height)) {
    NOTREACHED() << "Unable to decode image resource " << resource_id;
    return NULL;
  }

  return PNGDecoder::CreateSkBitmapFromBGRAFormat(png_data,
                                                  image_width,
                                                  image_height);
}

std::string ResourceBundle::GetDataResource(int resource_id) {
  return GetRawDataResource(resource_id).as_string();
}

bool ResourceBundle::LoadImageResourceBytes(int resource_id,
                                            std::vector<unsigned char>* bytes) {
  return LoadResourceBytes(theme_data_, resource_id, bytes);
}

bool ResourceBundle::LoadDataResourceBytes(int resource_id,
                                           std::vector<unsigned char>* bytes) {
  return LoadResourceBytes(resources_data_, resource_id, bytes);
}

SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) {
  // Check to see if we already have the Skia image in the cache.
  {
    AutoLock lock_scope(lock_);
    SkImageMap::const_iterator found = skia_images_.find(resource_id);
    if (found != skia_images_.end())
      return found->second;
  }

  scoped_ptr<SkBitmap> bitmap;

  if (theme_data_)
    bitmap.reset(LoadBitmap(theme_data_, resource_id));

  // If we did not find the bitmap in the theme DLL, try the current one.
  if (!bitmap.get())
    bitmap.reset(LoadBitmap(resources_data_, resource_id));

  // We loaded successfully.  Cache the Skia version of the bitmap.
  if (bitmap.get()) {
    AutoLock lock_scope(lock_);

    // Another thread raced us, and has already cached the skia image.
    if (skia_images_.count(resource_id))
      return skia_images_[resource_id];

    skia_images_[resource_id] = bitmap.get();
    return bitmap.release();
  }

  // We failed to retrieve the bitmap, show a debugging red square.
  {
    LOG(WARNING) << "Unable to load bitmap with id " << resource_id;
    NOTREACHED();  // Want to assert in debug mode.

    AutoLock lock_scope(lock_);  // Guard empty_bitmap initialization.

    static SkBitmap* empty_bitmap = NULL;
    if (!empty_bitmap) {
      // The placeholder bitmap is bright red so people notice the problem.
      // This bitmap will be leaked, but this code should never be hit.
      empty_bitmap = new SkBitmap();
      empty_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
      empty_bitmap->allocPixels();
      empty_bitmap->eraseARGB(255, 255, 0, 0);
    }
    return empty_bitmap;
  }
}

void ResourceBundle::LoadFontsIfNecessary() {
  AutoLock lock_scope(lock_);
  if (!base_font_.get()) {
    base_font_.reset(new gfx::Font());
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
    // Toolkit views needs a less gigantor base font to more correctly match
    // metrics for the bitmap-based UI.
    *base_font_ = base_font_->DeriveFont(-1);
#endif

    small_font_.reset(new gfx::Font());
    *small_font_ = base_font_->DeriveFont(-2);

    medium_font_.reset(new gfx::Font());
    *medium_font_ = base_font_->DeriveFont(3);

    medium_bold_font_.reset(new gfx::Font());
    *medium_bold_font_ =
        base_font_->DeriveFont(3, base_font_->style() | gfx::Font::BOLD);

    large_font_.reset(new gfx::Font());
    *large_font_ = base_font_->DeriveFont(8);
  }
}

gfx::Font ResourceBundle::GetFont(FontStyle style) {
  LoadFontsIfNecessary();
  switch(style) {
    case SmallFont:
      return *small_font_;
    case MediumFont:
      return *medium_font_;
    case MediumBoldFont:
      return *medium_bold_font_;
    case LargeFont:
      return *large_font_;
    default:
      return *base_font_;
  }
}
<|endoftext|>