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

#include "chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.h"

#include "build/build_config.h"
#include "chrome/browser/media/media_capture_devices_dispatcher.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_output_protection_private.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"

#if defined(OS_CHROMEOS)
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "chromeos/display/output_configurator.h"
#include "ui/aura/window.h"
#include "ui/gfx/screen.h"
#endif

namespace chrome {

namespace {

#if defined(OS_CHROMEOS)
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_NONE),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_UNKNOWN) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_UNKNOWN),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_UNKNOWN);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_INTERNAL),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_VGA),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_HDMI),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_DVI),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_DISPLAYPORT),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_NETWORK),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE) ==
    static_cast<int>(chromeos::OUTPUT_PROTECTION_METHOD_NONE),
    PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP) ==
    static_cast<int>(chromeos::OUTPUT_PROTECTION_METHOD_HDCP),
    PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP);

bool GetCurrentDisplayId(content::RenderFrameHost* rfh, int64* display_id) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  gfx::NativeView native_view = rfh->GetNativeView();
  gfx::Screen* screen = gfx::Screen::GetScreenFor(native_view);
  if (!screen)
    return false;
  gfx::Display display = screen->GetDisplayNearestWindow(native_view);
  *display_id = display.id();
  return true;
}
#endif

}  // namespace

#if defined(OS_CHROMEOS)
// Output protection delegate. All methods except constructor should be
// invoked in UI thread.
class PepperOutputProtectionMessageFilter::Delegate
    : public aura::WindowObserver {
 public:
  Delegate(int render_process_id, int render_frame_id);
  virtual ~Delegate();

  // aura::WindowObserver overrides.
  virtual void OnWindowHierarchyChanged(
      const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE;

  int32_t OnQueryStatus(uint32_t* link_mask, uint32_t* protection_mask);
  int32_t OnEnableProtection(uint32_t desired_method_mask);

 private:
  chromeos::OutputConfigurator::OutputProtectionClientId GetClientId();

  // Used to lookup the WebContents associated with this PP_Instance.
  int render_process_id_;
  int render_frame_id_;

  chromeos::OutputConfigurator::OutputProtectionClientId client_id_;
  // The display id which the renderer currently uses.
  int64 display_id_;
  // The last desired method mask. Will enable this mask on new display if
  // renderer changes display.
  uint32_t desired_method_mask_;
};

PepperOutputProtectionMessageFilter::Delegate::Delegate(int render_process_id,
                                                        int render_frame_id)
    : render_process_id_(render_process_id),
      render_frame_id_(render_frame_id),
      client_id_(chromeos::OutputConfigurator::kInvalidClientId),
      display_id_(0) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));

}

PepperOutputProtectionMessageFilter::Delegate::~Delegate() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  chromeos::OutputConfigurator* configurator =
      ash::Shell::GetInstance()->output_configurator();
  configurator->UnregisterOutputProtectionClient(client_id_);

  content::RenderFrameHost* rfh =
      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
  if (rfh) {
    gfx::NativeView native_view = rfh->GetNativeView();
    native_view->RemoveObserver(this);
  }
}

chromeos::OutputConfigurator::OutputProtectionClientId
PepperOutputProtectionMessageFilter::Delegate::GetClientId() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  if (client_id_ == chromeos::OutputConfigurator::kInvalidClientId) {
    content::RenderFrameHost* rfh =
        content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
    if (!GetCurrentDisplayId(rfh, &display_id_))
      return chromeos::OutputConfigurator::kInvalidClientId;
    gfx::NativeView native_view = rfh->GetNativeView();
    if (!native_view)
      return chromeos::OutputConfigurator::kInvalidClientId;
    native_view->AddObserver(this);

    chromeos::OutputConfigurator* configurator =
        ash::Shell::GetInstance()->output_configurator();
    client_id_ = configurator->RegisterOutputProtectionClient();
  }
  return client_id_;
}

int32_t PepperOutputProtectionMessageFilter::Delegate::OnQueryStatus(
    uint32_t* link_mask, uint32_t* protection_mask) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  content::RenderFrameHost* rfh =
      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
  if (!rfh) {
    LOG(WARNING) << "RenderFrameHost is not alive.";
    return PP_ERROR_FAILED;
  }

  chromeos::OutputConfigurator* configurator =
      ash::Shell::GetInstance()->output_configurator();
  bool result = configurator->QueryOutputProtectionStatus(
      GetClientId(), display_id_, link_mask, protection_mask);

  // If we successfully retrieved the device level status, check for capturers.
  if (result) {
    const bool capture_detected =
        // Check for tab capture on the current tab.
        content::WebContents::FromRenderFrameHost(rfh)->
            GetCapturerCount() > 0 ||
        // Check for desktop capture.
        MediaCaptureDevicesDispatcher::GetInstance()
            ->IsDesktopCaptureInProgress();
    if (capture_detected)
      *link_mask |= chromeos::OUTPUT_TYPE_NETWORK;
  }

  return result ? PP_OK : PP_ERROR_FAILED;
}

int32_t PepperOutputProtectionMessageFilter::Delegate::OnEnableProtection(
    uint32_t desired_method_mask) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  chromeos::OutputConfigurator* configurator =
      ash::Shell::GetInstance()->output_configurator();
  bool result = configurator->EnableOutputProtection(
      GetClientId(), display_id_, desired_method_mask);
  desired_method_mask_ = desired_method_mask;
  return result ? PP_OK : PP_ERROR_FAILED;
}

void PepperOutputProtectionMessageFilter::Delegate::OnWindowHierarchyChanged(
    const aura::WindowObserver::HierarchyChangeParams& params) {
  content::RenderFrameHost* rfh =
      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
  if (!rfh) {
    LOG(WARNING) << "RenderFrameHost is not alive.";
    return;
  }

  int64 new_display_id = 0;
  if (!GetCurrentDisplayId(rfh, &new_display_id))
    return;
  if (display_id_ == new_display_id)
    return;

  if (desired_method_mask_ != chromeos::OUTPUT_PROTECTION_METHOD_NONE) {
    // Display changed and should enable output protections on new display.
    chromeos::OutputConfigurator* configurator =
        ash::Shell::GetInstance()->output_configurator();
    configurator->EnableOutputProtection(GetClientId(), new_display_id,
                                         desired_method_mask_);
    configurator->EnableOutputProtection(
        GetClientId(),
        display_id_,
        chromeos::OUTPUT_PROTECTION_METHOD_NONE);
  }
  display_id_ = new_display_id;
}
#endif

PepperOutputProtectionMessageFilter::PepperOutputProtectionMessageFilter(
    content::BrowserPpapiHost* host,
    PP_Instance instance) {
#if defined(OS_CHROMEOS)
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  int render_process_id = 0;
  int render_frame_id = 0;
  host->GetRenderFrameIDsForInstance(
      instance, &render_process_id, &render_frame_id);
  delegate_ = new Delegate(render_process_id, render_frame_id);
#else
  NOTIMPLEMENTED();
#endif
}

PepperOutputProtectionMessageFilter::~PepperOutputProtectionMessageFilter() {
#if defined(OS_CHROMEOS)
  content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
                                     delegate_);
  delegate_ = NULL;
#endif
}

scoped_refptr<base::TaskRunner>
PepperOutputProtectionMessageFilter::OverrideTaskRunnerForMessage(
    const IPC::Message& message) {
  return content::BrowserThread::GetMessageLoopProxyForThread(
      content::BrowserThread::UI);
}

int32_t PepperOutputProtectionMessageFilter::OnResourceMessageReceived(
    const IPC::Message& msg,
    ppapi::host::HostMessageContext* context) {
  IPC_BEGIN_MESSAGE_MAP(PepperOutputProtectionMessageFilter, msg)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
        PpapiHostMsg_OutputProtection_QueryStatus,
        OnQueryStatus);
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
        PpapiHostMsg_OutputProtection_EnableProtection,
        OnEnableProtection);
  IPC_END_MESSAGE_MAP()
  return PP_ERROR_FAILED;
}

int32_t PepperOutputProtectionMessageFilter::OnQueryStatus(
    ppapi::host::HostMessageContext* context) {
#if defined(OS_CHROMEOS)
  uint32_t link_mask = 0, protection_mask = 0;
  int32_t result = delegate_->OnQueryStatus(&link_mask, &protection_mask);

  ppapi::host::ReplyMessageContext reply_context =
      context->MakeReplyMessageContext();
  reply_context.params.set_result(result);
  SendReply(
      reply_context,
      PpapiPluginMsg_OutputProtection_QueryStatusReply(
          link_mask, protection_mask));
  return PP_OK_COMPLETIONPENDING;
#else
  NOTIMPLEMENTED();
  return PP_ERROR_NOTSUPPORTED;
#endif
}

int32_t PepperOutputProtectionMessageFilter::OnEnableProtection(
    ppapi::host::HostMessageContext* context,
    uint32_t desired_method_mask) {
#if defined(OS_CHROMEOS)
  ppapi::host::ReplyMessageContext reply_context =
      context->MakeReplyMessageContext();
  int32_t result = delegate_->OnEnableProtection(desired_method_mask);
  reply_context.params.set_result(result);
  SendReply(
      reply_context,
      PpapiPluginMsg_OutputProtection_EnableProtectionReply());
  return PP_OK_COMPLETIONPENDING;
#else
  NOTIMPLEMENTED();
  return PP_ERROR_NOTSUPPORTED;
#endif
}

}  // namespace chrome

<commit_msg>Null-check RenderFrameHost::GetNativeView.<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.h"

#include "build/build_config.h"
#include "chrome/browser/media/media_capture_devices_dispatcher.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_output_protection_private.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"

#if defined(OS_CHROMEOS)
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "chromeos/display/output_configurator.h"
#include "ui/aura/window.h"
#include "ui/gfx/screen.h"
#endif

namespace chrome {

namespace {

#if defined(OS_CHROMEOS)
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_NONE),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_UNKNOWN) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_UNKNOWN),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_UNKNOWN);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_INTERNAL),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_VGA),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_HDMI),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_DVI),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_DISPLAYPORT),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK) ==
    static_cast<int>(chromeos::OUTPUT_TYPE_NETWORK),
    PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE) ==
    static_cast<int>(chromeos::OUTPUT_PROTECTION_METHOD_NONE),
    PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE);
COMPILE_ASSERT(
    static_cast<int>(PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP) ==
    static_cast<int>(chromeos::OUTPUT_PROTECTION_METHOD_HDCP),
    PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP);

bool GetCurrentDisplayId(content::RenderFrameHost* rfh, int64* display_id) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  gfx::NativeView native_view = rfh->GetNativeView();
  gfx::Screen* screen = gfx::Screen::GetScreenFor(native_view);
  if (!screen)
    return false;
  gfx::Display display = screen->GetDisplayNearestWindow(native_view);
  *display_id = display.id();
  return true;
}
#endif

}  // namespace

#if defined(OS_CHROMEOS)
// Output protection delegate. All methods except constructor should be
// invoked in UI thread.
class PepperOutputProtectionMessageFilter::Delegate
    : public aura::WindowObserver {
 public:
  Delegate(int render_process_id, int render_frame_id);
  virtual ~Delegate();

  // aura::WindowObserver overrides.
  virtual void OnWindowHierarchyChanged(
      const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE;

  int32_t OnQueryStatus(uint32_t* link_mask, uint32_t* protection_mask);
  int32_t OnEnableProtection(uint32_t desired_method_mask);

 private:
  chromeos::OutputConfigurator::OutputProtectionClientId GetClientId();

  // Used to lookup the WebContents associated with this PP_Instance.
  int render_process_id_;
  int render_frame_id_;

  chromeos::OutputConfigurator::OutputProtectionClientId client_id_;
  // The display id which the renderer currently uses.
  int64 display_id_;
  // The last desired method mask. Will enable this mask on new display if
  // renderer changes display.
  uint32_t desired_method_mask_;
};

PepperOutputProtectionMessageFilter::Delegate::Delegate(int render_process_id,
                                                        int render_frame_id)
    : render_process_id_(render_process_id),
      render_frame_id_(render_frame_id),
      client_id_(chromeos::OutputConfigurator::kInvalidClientId),
      display_id_(0) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));

}

PepperOutputProtectionMessageFilter::Delegate::~Delegate() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  chromeos::OutputConfigurator* configurator =
      ash::Shell::GetInstance()->output_configurator();
  configurator->UnregisterOutputProtectionClient(client_id_);

  content::RenderFrameHost* rfh =
      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
  if (rfh) {
    gfx::NativeView native_view = rfh->GetNativeView();
    if (native_view)
      native_view->RemoveObserver(this);
  }
}

chromeos::OutputConfigurator::OutputProtectionClientId
PepperOutputProtectionMessageFilter::Delegate::GetClientId() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  if (client_id_ == chromeos::OutputConfigurator::kInvalidClientId) {
    content::RenderFrameHost* rfh =
        content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
    if (!GetCurrentDisplayId(rfh, &display_id_))
      return chromeos::OutputConfigurator::kInvalidClientId;
    gfx::NativeView native_view = rfh->GetNativeView();
    if (!native_view)
      return chromeos::OutputConfigurator::kInvalidClientId;
    native_view->AddObserver(this);

    chromeos::OutputConfigurator* configurator =
        ash::Shell::GetInstance()->output_configurator();
    client_id_ = configurator->RegisterOutputProtectionClient();
  }
  return client_id_;
}

int32_t PepperOutputProtectionMessageFilter::Delegate::OnQueryStatus(
    uint32_t* link_mask, uint32_t* protection_mask) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  content::RenderFrameHost* rfh =
      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
  if (!rfh) {
    LOG(WARNING) << "RenderFrameHost is not alive.";
    return PP_ERROR_FAILED;
  }

  chromeos::OutputConfigurator* configurator =
      ash::Shell::GetInstance()->output_configurator();
  bool result = configurator->QueryOutputProtectionStatus(
      GetClientId(), display_id_, link_mask, protection_mask);

  // If we successfully retrieved the device level status, check for capturers.
  if (result) {
    const bool capture_detected =
        // Check for tab capture on the current tab.
        content::WebContents::FromRenderFrameHost(rfh)->
            GetCapturerCount() > 0 ||
        // Check for desktop capture.
        MediaCaptureDevicesDispatcher::GetInstance()
            ->IsDesktopCaptureInProgress();
    if (capture_detected)
      *link_mask |= chromeos::OUTPUT_TYPE_NETWORK;
  }

  return result ? PP_OK : PP_ERROR_FAILED;
}

int32_t PepperOutputProtectionMessageFilter::Delegate::OnEnableProtection(
    uint32_t desired_method_mask) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  chromeos::OutputConfigurator* configurator =
      ash::Shell::GetInstance()->output_configurator();
  bool result = configurator->EnableOutputProtection(
      GetClientId(), display_id_, desired_method_mask);
  desired_method_mask_ = desired_method_mask;
  return result ? PP_OK : PP_ERROR_FAILED;
}

void PepperOutputProtectionMessageFilter::Delegate::OnWindowHierarchyChanged(
    const aura::WindowObserver::HierarchyChangeParams& params) {
  content::RenderFrameHost* rfh =
      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
  if (!rfh) {
    LOG(WARNING) << "RenderFrameHost is not alive.";
    return;
  }

  int64 new_display_id = 0;
  if (!GetCurrentDisplayId(rfh, &new_display_id))
    return;
  if (display_id_ == new_display_id)
    return;

  if (desired_method_mask_ != chromeos::OUTPUT_PROTECTION_METHOD_NONE) {
    // Display changed and should enable output protections on new display.
    chromeos::OutputConfigurator* configurator =
        ash::Shell::GetInstance()->output_configurator();
    configurator->EnableOutputProtection(GetClientId(), new_display_id,
                                         desired_method_mask_);
    configurator->EnableOutputProtection(
        GetClientId(),
        display_id_,
        chromeos::OUTPUT_PROTECTION_METHOD_NONE);
  }
  display_id_ = new_display_id;
}
#endif

PepperOutputProtectionMessageFilter::PepperOutputProtectionMessageFilter(
    content::BrowserPpapiHost* host,
    PP_Instance instance) {
#if defined(OS_CHROMEOS)
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  int render_process_id = 0;
  int render_frame_id = 0;
  host->GetRenderFrameIDsForInstance(
      instance, &render_process_id, &render_frame_id);
  delegate_ = new Delegate(render_process_id, render_frame_id);
#else
  NOTIMPLEMENTED();
#endif
}

PepperOutputProtectionMessageFilter::~PepperOutputProtectionMessageFilter() {
#if defined(OS_CHROMEOS)
  content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
                                     delegate_);
  delegate_ = NULL;
#endif
}

scoped_refptr<base::TaskRunner>
PepperOutputProtectionMessageFilter::OverrideTaskRunnerForMessage(
    const IPC::Message& message) {
  return content::BrowserThread::GetMessageLoopProxyForThread(
      content::BrowserThread::UI);
}

int32_t PepperOutputProtectionMessageFilter::OnResourceMessageReceived(
    const IPC::Message& msg,
    ppapi::host::HostMessageContext* context) {
  IPC_BEGIN_MESSAGE_MAP(PepperOutputProtectionMessageFilter, msg)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
        PpapiHostMsg_OutputProtection_QueryStatus,
        OnQueryStatus);
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
        PpapiHostMsg_OutputProtection_EnableProtection,
        OnEnableProtection);
  IPC_END_MESSAGE_MAP()
  return PP_ERROR_FAILED;
}

int32_t PepperOutputProtectionMessageFilter::OnQueryStatus(
    ppapi::host::HostMessageContext* context) {
#if defined(OS_CHROMEOS)
  uint32_t link_mask = 0, protection_mask = 0;
  int32_t result = delegate_->OnQueryStatus(&link_mask, &protection_mask);

  ppapi::host::ReplyMessageContext reply_context =
      context->MakeReplyMessageContext();
  reply_context.params.set_result(result);
  SendReply(
      reply_context,
      PpapiPluginMsg_OutputProtection_QueryStatusReply(
          link_mask, protection_mask));
  return PP_OK_COMPLETIONPENDING;
#else
  NOTIMPLEMENTED();
  return PP_ERROR_NOTSUPPORTED;
#endif
}

int32_t PepperOutputProtectionMessageFilter::OnEnableProtection(
    ppapi::host::HostMessageContext* context,
    uint32_t desired_method_mask) {
#if defined(OS_CHROMEOS)
  ppapi::host::ReplyMessageContext reply_context =
      context->MakeReplyMessageContext();
  int32_t result = delegate_->OnEnableProtection(desired_method_mask);
  reply_context.params.set_result(result);
  SendReply(
      reply_context,
      PpapiPluginMsg_OutputProtection_EnableProtectionReply());
  return PP_OK_COMPLETIONPENDING;
#else
  NOTIMPLEMENTED();
  return PP_ERROR_NOTSUPPORTED;
#endif
}

}  // namespace chrome

<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2012 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2009-05-19
// Updated : 2009-05-19
// Licence : This source is under MIT License
// File    : glm/gtx/simd_mat4.hpp
///////////////////////////////////////////////////////////////////////////////////////////////////

namespace glm{
namespace detail{

GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::value_size()
{
	return sizeof(value_type);
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::col_size()
{
	return 4;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::row_size()
{
	return 4;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD()
{}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD(float const & s)
{
	this->Data[0] = fvec4SIMD(s, 0, 0, 0);
	this->Data[1] = fvec4SIMD(0, s, 0, 0);
	this->Data[2] = fvec4SIMD(0, 0, s, 0);
	this->Data[3] = fvec4SIMD(0, 0, 0, s);
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
(
	float const & x0, float const & y0, float const & z0, float const & w0,
	float const & x1, float const & y1, float const & z1, float const & w1,
	float const & x2, float const & y2, float const & z2, float const & w2,
	float const & x3, float const & y3, float const & z3, float const & w3
)
{
	this->Data[0] = fvec4SIMD(x0, y0, z0, w0);
	this->Data[1] = fvec4SIMD(x1, y1, z1, w1);
	this->Data[2] = fvec4SIMD(x2, y2, z2, w2);
	this->Data[3] = fvec4SIMD(x3, y3, z3, w3);
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
(
	fvec4SIMD const & v0,
	fvec4SIMD const & v1,
	fvec4SIMD const & v2,
	fvec4SIMD const & v3
)
{
	this->Data[0] = v0;
	this->Data[1] = v1;
	this->Data[2] = v2;
	this->Data[3] = v3;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
(
	tmat4x4<float> const & m
)
{
	this->Data[0] = fvec4SIMD(m[0]);
	this->Data[1] = fvec4SIMD(m[1]);
	this->Data[2] = fvec4SIMD(m[2]);
	this->Data[3] = fvec4SIMD(m[3]);
}

//////////////////////////////////////
// Accesses

GLM_FUNC_QUALIFIER fvec4SIMD & fmat4x4SIMD::operator[]
(
	fmat4x4SIMD::size_type i
)
{
	assert(
		i >= fmat4x4SIMD::size_type(0) &&
		i < fmat4x4SIMD::col_size());

	return this->Data[i];
}

GLM_FUNC_QUALIFIER fvec4SIMD const & fmat4x4SIMD::operator[]
(
	fmat4x4SIMD::size_type i
) const
{
	assert(
		i >= fmat4x4SIMD::size_type(0) &&
		i < fmat4x4SIMD::col_size());

	return this->Data[i];
}

//////////////////////////////////////////////////////////////
// mat4 operators

GLM_FUNC_QUALIFIER fmat4x4SIMD& fmat4x4SIMD::operator=
(
	fmat4x4SIMD const & m
)
{
	this->Data[0] = m[0];
	this->Data[1] = m[1];
	this->Data[2] = m[2];
	this->Data[3] = m[3];
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
(
	fmat4x4SIMD const & m
)
{
	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, m[0].Data);
	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, m[1].Data);
	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, m[2].Data);
	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, m[3].Data);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
(
	fmat4x4SIMD const & m
)
{
	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, m[0].Data);
	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, m[1].Data);
	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, m[2].Data);
	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, m[3].Data);

    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
(
	fmat4x4SIMD const & m
)
{
	sse_mul_ps(&this->Data[0].Data, &m.Data[0].Data, &this->Data[0].Data);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
(
	fmat4x4SIMD const & m
)
{
	__m128 Inv[4];
	sse_inverse_ps(&this->Data[0].Data, Inv);
	sse_mul_ps(&this->Data[0].Data, Inv, &this->Data[0].Data);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
(
	float const & s
)
{
	__m128 Operand = _mm_set_ps1(s);
	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, Operand);
	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, Operand);
	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, Operand);
	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, Operand);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
(
	float const & s
)
{
	__m128 Operand = _mm_set_ps1(s);
	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, Operand);
	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, Operand);
	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, Operand);
	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, Operand);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
(
	float const & s
)
{
	__m128 Operand = _mm_set_ps1(s);
	this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
	this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
	this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
	this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
(
	float const & s
)
{
	__m128 Operand = _mm_div_ps(one, _mm_set_ps1(s));
	this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
	this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
	this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
	this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator++ ()
{
	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, one);
	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, one);
	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, one);
	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, one);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-- ()
{
	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, one);
	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, one);
	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, one);
	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, one);
    return *this;
}

}//namespace detail

GLM_FUNC_QUALIFIER detail::tmat4x4<float> mat4_cast
(
	detail::fmat4x4SIMD const & x
)
{
	GLM_ALIGN(16) detail::tmat4x4<float> Result;
	_mm_store_ps(&Result[0][0], x.Data[0].Data);
	_mm_store_ps(&Result[1][0], x.Data[1].Data);
	_mm_store_ps(&Result[2][0], x.Data[2].Data);
	_mm_store_ps(&Result[3][0], x.Data[3].Data);
	return Result;
}

GLM_FUNC_QUALIFIER detail::fmat4x4SIMD matrixCompMult
(
	detail::fmat4x4SIMD const & x,
	detail::fmat4x4SIMD const & y
)
{
	detail::fmat4x4SIMD result;
	result[0] = x[0] * y[0];
	result[1] = x[1] * y[1];
	result[2] = x[2] * y[2];
	result[3] = x[3] * y[3];
	return result;
}

GLM_FUNC_QUALIFIER detail::fmat4x4SIMD outerProduct
(
	detail::fvec4SIMD const & c,
	detail::fvec4SIMD const & r
)
{
	__m128 Shu0 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(0, 0, 0, 0));
	__m128 Shu1 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(1, 1, 1, 1));
	__m128 Shu2 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(2, 2, 2, 2));
	__m128 Shu3 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(3, 3, 3, 3));

	detail::fmat4x4SIMD result(detail::fmat4x4SIMD::null);
	result[0].Data = _mm_mul_ps(c.Data, Shu0);
	result[1].Data = _mm_mul_ps(c.Data, Shu1);
	result[2].Data = _mm_mul_ps(c.Data, Shu2);
	result[3].Data = _mm_mul_ps(c.Data, Shu3);
	return result;
}

GLM_FUNC_QUALIFIER detail::fmat4x4SIMD transpose(detail::fmat4x4SIMD const & m)
{
	detail::fmat4x4SIMD result;
	detail::sse_transpose_ps(&m[0].Data, &result[0].Data);
	return result;
}

GLM_FUNC_QUALIFIER float determinant(detail::fmat4x4SIMD const & m)
{
	float Result;
	_mm_store_ss(&Result, detail::sse_det_ps(&m[0].Data));
	return Result;
}

GLM_FUNC_QUALIFIER detail::fmat4x4SIMD inverse(detail::fmat4x4SIMD const & m)
{
	detail::fmat4x4SIMD result;
	detail::sse_inverse_ps(&m[0].Data, &result[0].Data);
	return result;
}

}//namespace glm
<commit_msg>Fixed ticket 169, parameter not used for mat division<commit_after>///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2012 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2009-05-19
// Updated : 2009-05-19
// Licence : This source is under MIT License
// File    : glm/gtx/simd_mat4.hpp
///////////////////////////////////////////////////////////////////////////////////////////////////

namespace glm{
namespace detail{

GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::value_size()
{
	return sizeof(value_type);
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::col_size()
{
	return 4;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::row_size()
{
	return 4;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD()
{}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD(float const & s)
{
	this->Data[0] = fvec4SIMD(s, 0, 0, 0);
	this->Data[1] = fvec4SIMD(0, s, 0, 0);
	this->Data[2] = fvec4SIMD(0, 0, s, 0);
	this->Data[3] = fvec4SIMD(0, 0, 0, s);
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
(
	float const & x0, float const & y0, float const & z0, float const & w0,
	float const & x1, float const & y1, float const & z1, float const & w1,
	float const & x2, float const & y2, float const & z2, float const & w2,
	float const & x3, float const & y3, float const & z3, float const & w3
)
{
	this->Data[0] = fvec4SIMD(x0, y0, z0, w0);
	this->Data[1] = fvec4SIMD(x1, y1, z1, w1);
	this->Data[2] = fvec4SIMD(x2, y2, z2, w2);
	this->Data[3] = fvec4SIMD(x3, y3, z3, w3);
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
(
	fvec4SIMD const & v0,
	fvec4SIMD const & v1,
	fvec4SIMD const & v2,
	fvec4SIMD const & v3
)
{
	this->Data[0] = v0;
	this->Data[1] = v1;
	this->Data[2] = v2;
	this->Data[3] = v3;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
(
	tmat4x4<float> const & m
)
{
	this->Data[0] = fvec4SIMD(m[0]);
	this->Data[1] = fvec4SIMD(m[1]);
	this->Data[2] = fvec4SIMD(m[2]);
	this->Data[3] = fvec4SIMD(m[3]);
}

//////////////////////////////////////
// Accesses

GLM_FUNC_QUALIFIER fvec4SIMD & fmat4x4SIMD::operator[]
(
	fmat4x4SIMD::size_type i
)
{
	assert(
		i >= fmat4x4SIMD::size_type(0) &&
		i < fmat4x4SIMD::col_size());

	return this->Data[i];
}

GLM_FUNC_QUALIFIER fvec4SIMD const & fmat4x4SIMD::operator[]
(
	fmat4x4SIMD::size_type i
) const
{
	assert(
		i >= fmat4x4SIMD::size_type(0) &&
		i < fmat4x4SIMD::col_size());

	return this->Data[i];
}

//////////////////////////////////////////////////////////////
// mat4 operators

GLM_FUNC_QUALIFIER fmat4x4SIMD& fmat4x4SIMD::operator=
(
	fmat4x4SIMD const & m
)
{
	this->Data[0] = m[0];
	this->Data[1] = m[1];
	this->Data[2] = m[2];
	this->Data[3] = m[3];
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
(
	fmat4x4SIMD const & m
)
{
	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, m[0].Data);
	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, m[1].Data);
	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, m[2].Data);
	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, m[3].Data);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
(
	fmat4x4SIMD const & m
)
{
	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, m[0].Data);
	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, m[1].Data);
	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, m[2].Data);
	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, m[3].Data);

    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
(
	fmat4x4SIMD const & m
)
{
	sse_mul_ps(&this->Data[0].Data, &m.Data[0].Data, &this->Data[0].Data);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
(
	fmat4x4SIMD const & m
)
{
	__m128 Inv[4];
	sse_inverse_ps(&m.Data[0].Data, Inv);
	sse_mul_ps(&this->Data[0].Data, Inv, &this->Data[0].Data);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
(
	float const & s
)
{
	__m128 Operand = _mm_set_ps1(s);
	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, Operand);
	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, Operand);
	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, Operand);
	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, Operand);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
(
	float const & s
)
{
	__m128 Operand = _mm_set_ps1(s);
	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, Operand);
	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, Operand);
	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, Operand);
	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, Operand);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
(
	float const & s
)
{
	__m128 Operand = _mm_set_ps1(s);
	this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
	this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
	this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
	this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
(
	float const & s
)
{
	__m128 Operand = _mm_div_ps(one, _mm_set_ps1(s));
	this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
	this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
	this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
	this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator++ ()
{
	this->Data[0].Data = _mm_add_ps(this->Data[0].Data, one);
	this->Data[1].Data = _mm_add_ps(this->Data[1].Data, one);
	this->Data[2].Data = _mm_add_ps(this->Data[2].Data, one);
	this->Data[3].Data = _mm_add_ps(this->Data[3].Data, one);
    return *this;
}

GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-- ()
{
	this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, one);
	this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, one);
	this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, one);
	this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, one);
    return *this;
}

}//namespace detail

GLM_FUNC_QUALIFIER detail::tmat4x4<float> mat4_cast
(
	detail::fmat4x4SIMD const & x
)
{
	GLM_ALIGN(16) detail::tmat4x4<float> Result;
	_mm_store_ps(&Result[0][0], x.Data[0].Data);
	_mm_store_ps(&Result[1][0], x.Data[1].Data);
	_mm_store_ps(&Result[2][0], x.Data[2].Data);
	_mm_store_ps(&Result[3][0], x.Data[3].Data);
	return Result;
}

GLM_FUNC_QUALIFIER detail::fmat4x4SIMD matrixCompMult
(
	detail::fmat4x4SIMD const & x,
	detail::fmat4x4SIMD const & y
)
{
	detail::fmat4x4SIMD result;
	result[0] = x[0] * y[0];
	result[1] = x[1] * y[1];
	result[2] = x[2] * y[2];
	result[3] = x[3] * y[3];
	return result;
}

GLM_FUNC_QUALIFIER detail::fmat4x4SIMD outerProduct
(
	detail::fvec4SIMD const & c,
	detail::fvec4SIMD const & r
)
{
	__m128 Shu0 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(0, 0, 0, 0));
	__m128 Shu1 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(1, 1, 1, 1));
	__m128 Shu2 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(2, 2, 2, 2));
	__m128 Shu3 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(3, 3, 3, 3));

	detail::fmat4x4SIMD result(detail::fmat4x4SIMD::null);
	result[0].Data = _mm_mul_ps(c.Data, Shu0);
	result[1].Data = _mm_mul_ps(c.Data, Shu1);
	result[2].Data = _mm_mul_ps(c.Data, Shu2);
	result[3].Data = _mm_mul_ps(c.Data, Shu3);
	return result;
}

GLM_FUNC_QUALIFIER detail::fmat4x4SIMD transpose(detail::fmat4x4SIMD const & m)
{
	detail::fmat4x4SIMD result;
	detail::sse_transpose_ps(&m[0].Data, &result[0].Data);
	return result;
}

GLM_FUNC_QUALIFIER float determinant(detail::fmat4x4SIMD const & m)
{
	float Result;
	_mm_store_ss(&Result, detail::sse_det_ps(&m[0].Data));
	return Result;
}

GLM_FUNC_QUALIFIER detail::fmat4x4SIMD inverse(detail::fmat4x4SIMD const & m)
{
	detail::fmat4x4SIMD result;
	detail::sse_inverse_ps(&m[0].Data, &result[0].Data);
	return result;
}

}//namespace glm
<|endoftext|>


<commit_before>#ifndef QTL_REGION_CLASSIFIER_HPP_
#define QTL_REGION_CLASSIFIER_HPP_

#include "qtl_allele.h"
#include "clotho/utility/random_generator.hpp"
#include "clotho/classifiers/region_classifier.hpp"

#include <boost/random/poisson_distribution.hpp>

namespace clotho {
namespace utility {

template < class URNG, class Result, class Tag >
class random_generator< URNG, clotho::classifiers::region_classifier< qtl_allele, Result, Tag > > {
public:
    typedef random_generator< URNG, clotho::classifiers::region_classifier< qtl_allele, Result, Tag > > self_type;
    typedef clotho::classifiers::region_classifier< qtl_allele, Result, Tag >   result_type;

    typedef boost::random::uniform_01< double >                                 uniform_type;   // key distribution
    typedef boost::random::poisson_distribution< unsigned int, double >         dist_type;      // region distribution

    random_generator( URNG & rng, boost::property_tree::ptree & config ) :
        m_rng( &rng )
        , m_dist( DEFAULT_RECOMB_RATE )
        , m_bSkip(false) {
        parseConfig( config );
    }

    random_generator( URNG & rng, double mu = DEFAULT_RECOMB_RATE ) :
        m_rng( &rng ), m_dist( mu ) {
    }

    result_type operator()() {
        typename result_type::param_type p;

        unsigned int n = ((m_bSkip)? 0 : m_dist( *m_rng ));

        for( unsigned int i = 0; i < n; ++i ) {
            double k = m_uniform( *m_rng );
            qtl_allele::trait_weights coeff;

            p.push_back( qtl_allele( k, DEFAULT_SELECTION, DEFAULT_DOMINANCE, DEFAULT_NEUTRAL, 0, coeff) );
        }

        std::sort( p.begin(), p.end() );
        return result_type( p );
    }

protected:

    void parseConfig( boost::property_tree::ptree & config ) {
        std::ostringstream oss;
        oss /*<< CONFIG_BLOCK_K << "."*/ << REC_BLOCK_K << "." << RATE_PER_REGION_K;

        if( config.get_child_optional( oss.str() ) == boost::none ) {
            config.put( oss.str(), m_dist.mean() );
        } else {
            double m = config.get< double >( oss.str() );

            m_bSkip = (m == 0.0);

            if( m_bSkip ) {
                m = 0.00000000001;
            } else if( m < 0.0 ) {
                m = std::abs( m );
            }

            typename dist_type::param_type p( m );

            m_dist.param( p );
        }
    }

    URNG        * m_rng;
    uniform_type    m_uniform;
    dist_type       m_dist;
    bool        m_bSkip;
};

}   // namespace utility {
}   // namespace clotho {

#endif  // QTL_REGION_CLASSIFIER_HPP_
<commit_msg>Modified to guarantee unique breakpoints are generated; Considering using geometric distribution rather than poisson and uniform<commit_after>#ifndef QTL_REGION_CLASSIFIER_HPP_
#define QTL_REGION_CLASSIFIER_HPP_

#include "qtl_allele.h"
#include "clotho/utility/random_generator.hpp"
#include "clotho/classifiers/region_classifier.hpp"

#include <boost/random/poisson_distribution.hpp>
#include <set>

namespace clotho {
namespace utility {

template < class URNG, class Result, class Tag >
class random_generator< URNG, clotho::classifiers::region_classifier< qtl_allele, Result, Tag > > {
public:
    typedef random_generator< URNG, clotho::classifiers::region_classifier< qtl_allele, Result, Tag > > self_type;
    typedef clotho::classifiers::region_classifier< qtl_allele, Result, Tag >   result_type;

    typedef boost::random::uniform_01< double >                                 uniform_type;   // key distribution
    typedef boost::random::poisson_distribution< unsigned int, double >         dist_type;      // region distribution

    random_generator( URNG & rng, boost::property_tree::ptree & config ) :
        m_rng( &rng )
        , m_dist( DEFAULT_RECOMB_RATE )
        , m_bSkip(false) {
        parseConfig( config );
    }

    random_generator( URNG & rng, double mu = DEFAULT_RECOMB_RATE ) :
        m_rng( &rng ), m_dist( mu ) {
    }

    result_type operator()() {
        typename result_type::param_type p;

        unsigned int n = ((m_bSkip)? 0 : m_dist( *m_rng ));

        if( n ) {
            std::set< double > positions;
            while( positions.size() < n ) {
                positions.insert( m_uniform( *m_rng ) );
            }

            qtl_allele::trait_weights coeff;
            for( std::set< double >::iterator it = positions.begin(); it != positions.end(); ++it ) {
                p.push_back( qtl_allele( *it, DEFAULT_SELECTION, DEFAULT_DOMINANCE, DEFAULT_NEUTRAL, 0, coeff) );
            }
        }
        return result_type( p );
    }

protected:

    void parseConfig( boost::property_tree::ptree & config ) {
        std::ostringstream oss;
        oss /*<< CONFIG_BLOCK_K << "."*/ << REC_BLOCK_K << "." << RATE_PER_REGION_K;

        if( config.get_child_optional( oss.str() ) == boost::none ) {
            config.put( oss.str(), m_dist.mean() );
        } else {
            double m = config.get< double >( oss.str() );

            m_bSkip = (m == 0.0);

            if( m_bSkip ) {
                m = 0.00000000001;
            } else if( m < 0.0 ) {
                m = std::abs( m );
            }

            typename dist_type::param_type p( m );

            m_dist.param( p );
        }
    }

    URNG        * m_rng;
    uniform_type    m_uniform;
    dist_type       m_dist;
    bool        m_bSkip;
};

}   // namespace utility {
}   // namespace clotho {

#endif  // QTL_REGION_CLASSIFIER_HPP_
<|endoftext|>


<commit_before>#include <improbable/standard_library.h>
#include <improbable/worker.h>
#include <shoveler.h>

extern "C" {
#include <shoveler/camera/perspective.h>
#include <shoveler/light/point.h>
#include <shoveler/constants.h>
#include <shoveler/game.h>
#include <shoveler/log.h>
#include <shoveler/types.h>

#include "worker_view.h"
}

using shoveler::Drawable;
using shoveler::DrawableType;
using shoveler::Material;
using shoveler::MaterialType;
using shoveler::Model;
using improbable::Coordinates;
using improbable::Position;

static void updateGame(ShovelerGame *game, double dt);
static ShovelerSpatialOsWorkerViewDrawableConfiguration createDrawableConfiguration(const Drawable& drawable);
static ShovelerSpatialOsWorkerViewMaterialConfiguration createMaterialConfiguration(const Material& material);

int main(int argc, char **argv) {
	if (argc != 4) {
		return 1;
	}

	const char *windowTitle = "ShovelerClient";
	bool fullscreen = false;
	bool vsync = true;
	int samples = 4;
	int width = 640;
	int height = 480;

	ShovelerGame *game = shovelerGameCreate(windowTitle, width, height, samples, fullscreen, vsync);
	if(game == NULL) {
		return EXIT_FAILURE;
	}

	worker::ConnectionParameters parameters;
	parameters.WorkerType = "ShovelerClient";
	parameters.Network.ConnectionType = worker::NetworkConnectionType::kTcp;
	parameters.Network.UseExternalIp = false;

	const std::string workerId = argv[1];
	const std::string hostname = argv[2];
	const std::uint16_t port = static_cast<std::uint16_t>(std::stoi(argv[3]));

	shovelerLogInfo("Connecting as worker %s to %s:%d.", workerId.c_str(), hostname.c_str(), port);
	worker::Connection connection = worker::Connection::ConnectAsync(hostname, port, workerId, parameters).Get();
	bool disconnected = false;
	worker::Dispatcher dispatcher;

	game->camera = shovelerCameraPerspectiveCreate(ShovelerVector3{0.0, 0.0, -1.0}, ShovelerVector3{0.0, 0.0, 1.0}, ShovelerVector3{0.0, 1.0, 0.0}, 2.0f * SHOVELER_PI * 50.0f / 360.0f, (float) width / height, 0.01, 1000);
	game->scene = shovelerSceneCreate();
	game->update = updateGame;
	ShovelerSpatialOsWorkerView *view = shovelerSpatialOsWorkerViewCreate(game->scene);

	dispatcher.OnDisconnect([&](const worker::DisconnectOp& op) {
		shovelerLogError("Disconnected from SpatialOS: %s", op.Reason.c_str());
		disconnected = true;
	});

	dispatcher.OnAddEntity([&](const worker::AddEntityOp& op) {
		shovelerLogInfo("Adding entity %lld.", op.EntityId);
		shovelerSpatialOsWorkerViewAddEntity(view, op.EntityId);
	});

	dispatcher.OnRemoveEntity([&](const worker::RemoveEntityOp& op) {
		shovelerLogInfo("Removing entity %lld.", op.EntityId);
		shovelerSpatialOsWorkerViewRemoveEntity(view, op.EntityId);
	});

	dispatcher.OnAddComponent<Position>([&](const worker::AddComponentOp<Position>& op) {
		shovelerLogInfo("Adding position to entity %lld.", op.EntityId);
		ShovelerVector3 position{(float) op.Data.coords().x(), (float) op.Data.coords().y(), (float) op.Data.coords().z()};
		shovelerSpatialOsWorkerViewAddEntityPosition(view, op.EntityId, position);
	});

	dispatcher.OnComponentUpdate<Position>([&](const worker::ComponentUpdateOp<Position>& op) {
		shovelerLogInfo("Updating position for entity %lld.", op.EntityId);
		if(op.Update.coords()) {
			const Coordinates& coordinates = *op.Update.coords();
			ShovelerVector3 position{(float) coordinates.x(), (float) coordinates.y(), (float) coordinates.z()};
			shovelerSpatialOsWorkerViewUpdateEntityPosition(view, op.EntityId, position);
		}
	});

	dispatcher.OnRemoveComponent<Position>([&](const worker::RemoveComponentOp& op) {
		shovelerLogInfo("Removing position from entity %lld.", op.EntityId);
		shovelerSpatialOsWorkerViewRemoveEntityPosition(view, op.EntityId);
	});

	dispatcher.OnAddComponent<Model>([&](const worker::AddComponentOp<Model>& op) {
		shovelerLogInfo("Adding model to entity %lld.", op.EntityId);
		ShovelerSpatialOsWorkerViewDrawableConfiguration drawableConfiguration = createDrawableConfiguration(op.Data.drawable());
		ShovelerSpatialOsWorkerViewMaterialConfiguration materialConfiguration = createMaterialConfiguration(op.Data.material());
		shovelerSpatialOsWorkerViewAddEntityModel(view, op.EntityId, drawableConfiguration, materialConfiguration);
	});

	dispatcher.OnComponentUpdate<Model>([&](const worker::ComponentUpdateOp<Model>& op) {
		shovelerLogInfo("Updating model for entity %lld.", op.EntityId);

		ShovelerSpatialOsWorkerViewDrawableConfiguration drawableConfiguration;
		ShovelerSpatialOsWorkerViewDrawableConfiguration *optionalDrawableConfiguration = NULL;
		if(op.Update.drawable()) {
			drawableConfiguration = createDrawableConfiguration(*op.Update.drawable());
			optionalDrawableConfiguration = &drawableConfiguration;
		}

		ShovelerSpatialOsWorkerViewMaterialConfiguration materialConfiguration;
		ShovelerSpatialOsWorkerViewMaterialConfiguration *optionalMaterialConfiguration = NULL;
		if(op.Update.material()) {
			materialConfiguration = createMaterialConfiguration(*op.Update.material());
			optionalMaterialConfiguration = &materialConfiguration;
		}

		shovelerSpatialOsWorkerViewUpdateEntityModel(view, op.EntityId, optionalDrawableConfiguration, optionalMaterialConfiguration);
	});

	dispatcher.OnRemoveComponent<Model>([&](const worker::RemoveComponentOp& op) {
		shovelerLogInfo("Removing model from entity %lld.", op.EntityId);
		shovelerSpatialOsWorkerViewRemoveEntityModel(view, op.EntityId);
	});

	ShovelerLightPoint *pointlight = shovelerLightPointCreate((ShovelerVector3){0, 5, 0}, 1024, 1024, 1, 0.0f, 80.0f, (ShovelerVector3){1.0f, 1.0f, 1.0f});
	shovelerSceneAddLight(game->scene, &pointlight->light);

	while(shovelerGameIsRunning(game) && !disconnected) {
		dispatcher.Process(connection.GetOpList(0));
		shovelerGameRenderFrame(game);
	}
	shovelerLogInfo("Exiting main loop, goodbye.");

	shovelerSpatialOsWorkerViewFree(view);

	shovelerCameraFree(game->camera);
	shovelerSceneFree(game->scene);

	shovelerGameFree(game);
}

static void updateGame(ShovelerGame *game, double dt)
{

}

static ShovelerSpatialOsWorkerViewDrawableConfiguration createDrawableConfiguration(const Drawable& drawable)
{
	ShovelerSpatialOsWorkerViewDrawableConfiguration drawableConfiguration;
	switch(drawable.type()) {
		case DrawableType::CUBE:
			drawableConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_DRAWABLE_TYPE_CUBE;
			break;
		case DrawableType::QUAD:
			drawableConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_DRAWABLE_TYPE_QUAD;
			break;
		default:
			shovelerLogWarning("Tried to create drawable configuration with invalid drawable type %d, defaulting to cube.", drawable.type());
			drawableConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_DRAWABLE_TYPE_CUBE;
			break;
	}
	return drawableConfiguration;
}

static ShovelerSpatialOsWorkerViewMaterialConfiguration createMaterialConfiguration(const Material& material)
{
	ShovelerSpatialOsWorkerViewMaterialConfiguration materialConfiguration;
	switch(material.type()) {
		case MaterialType::COLOR:
			materialConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_MATERIAL_TYPE_COLOR;
			materialConfiguration.color = ShovelerVector3{material.color().r(), material.color().g(), material.color().b()};
			break;
		case MaterialType::TEXTURE:
			materialConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_MATERIAL_TYPE_TEXTURE;
			materialConfiguration.texture = material.texture().c_str();
			break;
		default:
			shovelerLogWarning("Tried to create material configuration with invalid material type %d, defaulting to color.", material.type());
			materialConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_MATERIAL_TYPE_COLOR;
			materialConfiguration.color = ShovelerVector3{material.color().r(), material.color().g(), material.color().b()};
			break;
	}
	return materialConfiguration;
}
<commit_msg>fixed client build on Windows<commit_after>#include <improbable/standard_library.h>
#include <improbable/worker.h>
#include <shoveler.h>

extern "C" {
#include <shoveler/camera/perspective.h>
#include <shoveler/light/point.h>
#include <shoveler/constants.h>
#include <shoveler/game.h>
#include <shoveler/log.h>
#include <shoveler/types.h>

#include "worker_view.h"
}

using shoveler::Drawable;
using shoveler::DrawableType;
using shoveler::Material;
using shoveler::MaterialType;
using shoveler::Model;
using improbable::Coordinates;
using improbable::Position;

static void updateGame(ShovelerGame *game, double dt);
static ShovelerSpatialOsWorkerViewDrawableConfiguration createDrawableConfiguration(const Drawable& drawable);
static ShovelerSpatialOsWorkerViewMaterialConfiguration createMaterialConfiguration(const Material& material);

int main(int argc, char **argv) {
	if (argc != 4) {
		return 1;
	}

	const char *windowTitle = "ShovelerClient";
	bool fullscreen = false;
	bool vsync = true;
	int samples = 4;
	int width = 640;
	int height = 480;

	ShovelerGame *game = shovelerGameCreate(windowTitle, width, height, samples, fullscreen, vsync);
	if(game == NULL) {
		return EXIT_FAILURE;
	}

	worker::ConnectionParameters parameters;
	parameters.WorkerType = "ShovelerClient";
	parameters.Network.ConnectionType = worker::NetworkConnectionType::kTcp;
	parameters.Network.UseExternalIp = false;

	const std::string workerId = argv[1];
	const std::string hostname = argv[2];
	const std::uint16_t port = static_cast<std::uint16_t>(std::stoi(argv[3]));

	shovelerLogInfo("Connecting as worker %s to %s:%d.", workerId.c_str(), hostname.c_str(), port);
	worker::Connection connection = worker::Connection::ConnectAsync(hostname, port, workerId, parameters).Get();
	bool disconnected = false;
	worker::Dispatcher dispatcher;

	game->camera = shovelerCameraPerspectiveCreate(ShovelerVector3{0.0, 0.0, -1.0}, ShovelerVector3{0.0, 0.0, 1.0}, ShovelerVector3{0.0, 1.0, 0.0}, 2.0f * SHOVELER_PI * 50.0f / 360.0f, (float) width / height, 0.01, 1000);
	game->scene = shovelerSceneCreate();
	game->update = updateGame;
	ShovelerSpatialOsWorkerView *view = shovelerSpatialOsWorkerViewCreate(game->scene);

	dispatcher.OnDisconnect([&](const worker::DisconnectOp& op) {
		shovelerLogError("Disconnected from SpatialOS: %s", op.Reason.c_str());
		disconnected = true;
	});

	dispatcher.OnAddEntity([&](const worker::AddEntityOp& op) {
		shovelerLogInfo("Adding entity %lld.", op.EntityId);
		shovelerSpatialOsWorkerViewAddEntity(view, op.EntityId);
	});

	dispatcher.OnRemoveEntity([&](const worker::RemoveEntityOp& op) {
		shovelerLogInfo("Removing entity %lld.", op.EntityId);
		shovelerSpatialOsWorkerViewRemoveEntity(view, op.EntityId);
	});

	dispatcher.OnAddComponent<Position>([&](const worker::AddComponentOp<Position>& op) {
		shovelerLogInfo("Adding position to entity %lld.", op.EntityId);
		ShovelerVector3 position{(float) op.Data.coords().x(), (float) op.Data.coords().y(), (float) op.Data.coords().z()};
		shovelerSpatialOsWorkerViewAddEntityPosition(view, op.EntityId, position);
	});

	dispatcher.OnComponentUpdate<Position>([&](const worker::ComponentUpdateOp<Position>& op) {
		shovelerLogInfo("Updating position for entity %lld.", op.EntityId);
		if(op.Update.coords()) {
			const Coordinates& coordinates = *op.Update.coords();
			ShovelerVector3 position{(float) coordinates.x(), (float) coordinates.y(), (float) coordinates.z()};
			shovelerSpatialOsWorkerViewUpdateEntityPosition(view, op.EntityId, position);
		}
	});

	dispatcher.OnRemoveComponent<Position>([&](const worker::RemoveComponentOp& op) {
		shovelerLogInfo("Removing position from entity %lld.", op.EntityId);
		shovelerSpatialOsWorkerViewRemoveEntityPosition(view, op.EntityId);
	});

	dispatcher.OnAddComponent<Model>([&](const worker::AddComponentOp<Model>& op) {
		shovelerLogInfo("Adding model to entity %lld.", op.EntityId);
		ShovelerSpatialOsWorkerViewDrawableConfiguration drawableConfiguration = createDrawableConfiguration(op.Data.drawable());
		ShovelerSpatialOsWorkerViewMaterialConfiguration materialConfiguration = createMaterialConfiguration(op.Data.material());
		shovelerSpatialOsWorkerViewAddEntityModel(view, op.EntityId, drawableConfiguration, materialConfiguration);
	});

	dispatcher.OnComponentUpdate<Model>([&](const worker::ComponentUpdateOp<Model>& op) {
		shovelerLogInfo("Updating model for entity %lld.", op.EntityId);

		ShovelerSpatialOsWorkerViewDrawableConfiguration drawableConfiguration;
		ShovelerSpatialOsWorkerViewDrawableConfiguration *optionalDrawableConfiguration = NULL;
		if(op.Update.drawable()) {
			drawableConfiguration = createDrawableConfiguration(*op.Update.drawable());
			optionalDrawableConfiguration = &drawableConfiguration;
		}

		ShovelerSpatialOsWorkerViewMaterialConfiguration materialConfiguration;
		ShovelerSpatialOsWorkerViewMaterialConfiguration *optionalMaterialConfiguration = NULL;
		if(op.Update.material()) {
			materialConfiguration = createMaterialConfiguration(*op.Update.material());
			optionalMaterialConfiguration = &materialConfiguration;
		}

		shovelerSpatialOsWorkerViewUpdateEntityModel(view, op.EntityId, optionalDrawableConfiguration, optionalMaterialConfiguration);
	});

	dispatcher.OnRemoveComponent<Model>([&](const worker::RemoveComponentOp& op) {
		shovelerLogInfo("Removing model from entity %lld.", op.EntityId);
		shovelerSpatialOsWorkerViewRemoveEntityModel(view, op.EntityId);
	});

	ShovelerLightPoint *pointlight = shovelerLightPointCreate(ShovelerVector3{0, 5, 0}, 1024, 1024, 1, 0.0f, 80.0f, ShovelerVector3{1.0f, 1.0f, 1.0f});
	shovelerSceneAddLight(game->scene, &pointlight->light);

	while(shovelerGameIsRunning(game) && !disconnected) {
		dispatcher.Process(connection.GetOpList(0));
		shovelerGameRenderFrame(game);
	}
	shovelerLogInfo("Exiting main loop, goodbye.");

	shovelerSpatialOsWorkerViewFree(view);

	shovelerCameraFree(game->camera);
	shovelerSceneFree(game->scene);

	shovelerGameFree(game);
}

static void updateGame(ShovelerGame *game, double dt)
{

}

static ShovelerSpatialOsWorkerViewDrawableConfiguration createDrawableConfiguration(const Drawable& drawable)
{
	ShovelerSpatialOsWorkerViewDrawableConfiguration drawableConfiguration;
	switch(drawable.type()) {
		case DrawableType::CUBE:
			drawableConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_DRAWABLE_TYPE_CUBE;
			break;
		case DrawableType::QUAD:
			drawableConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_DRAWABLE_TYPE_QUAD;
			break;
		default:
			shovelerLogWarning("Tried to create drawable configuration with invalid drawable type %d, defaulting to cube.", drawable.type());
			drawableConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_DRAWABLE_TYPE_CUBE;
			break;
	}
	return drawableConfiguration;
}

static ShovelerSpatialOsWorkerViewMaterialConfiguration createMaterialConfiguration(const Material& material)
{
	ShovelerSpatialOsWorkerViewMaterialConfiguration materialConfiguration;
	switch(material.type()) {
		case MaterialType::COLOR:
			materialConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_MATERIAL_TYPE_COLOR;
			materialConfiguration.color = ShovelerVector3{material.color().r(), material.color().g(), material.color().b()};
			break;
		case MaterialType::TEXTURE:
			materialConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_MATERIAL_TYPE_TEXTURE;
			materialConfiguration.texture = material.texture().c_str();
			break;
		default:
			shovelerLogWarning("Tried to create material configuration with invalid material type %d, defaulting to color.", material.type());
			materialConfiguration.type = SHOVELER_SPATIALOS_WORKER_VIEW_MATERIAL_TYPE_COLOR;
			materialConfiguration.color = ShovelerVector3{material.color().r(), material.color().g(), material.color().b()};
			break;
	}
	return materialConfiguration;
}
<|endoftext|>


<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file linear_process_model.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__MODEL__PROCESS__LINEAR_GAUSSIAN_PROCESS_MODEL_HPP
#define FL__MODEL__PROCESS__LINEAR_GAUSSIAN_PROCESS_MODEL_HPP

#include <fl/util/traits.hpp>
#include <fl/distribution/gaussian.hpp>
#include <fl/model/process/process_model_interface.hpp>

namespace fl
{

// Forward declarations
template <typename State, typename Input_> class LinearGaussianProcessModel;

/**
 * Linear Gaussian process model traits. This trait definition contains all
 * types used internally within the linear model. Additionally, it provides the
 * types needed externally to use the model.
 */
template <typename State_, typename Input_>
struct Traits<LinearGaussianProcessModel<State_, Input_>>
{
    typedef Gaussian<State_> GaussianBase;

    typedef State_ State;
    typedef Input_ Input;
    typedef typename Traits<GaussianBase>::Scalar Scalar;
    typedef typename Traits<GaussianBase>::SecondMoment SecondMoment;
    typedef typename Traits<GaussianBase>::StandardVariate Noise;

    typedef ProcessModelInterface<State, Noise, Input> ProcessModelBase;

    typedef Eigen::Matrix<Scalar,
                          State::SizeAtCompileTime,
                          State::SizeAtCompileTime> DynamicsMatrix;
};

/**
 * \ingroup process_models
 * \warning correct input parameter
 * \todo correct input parameter
 */
template <typename State_, typename Input_ = Eigen::Matrix<double, 1, 1>>
class LinearGaussianProcessModel:
    public Traits<LinearGaussianProcessModel<State_, Input_>>::ProcessModelBase,
    public Traits<LinearGaussianProcessModel<State_, Input_>>::GaussianBase
{
public:
    typedef LinearGaussianProcessModel<State_, Input_> This;

    typedef typename Traits<This>::State State;
    typedef typename Traits<This>::Input Input;
    typedef typename Traits<This>::Noise Noise;
    typedef typename Traits<This>::Scalar Scalar;
    typedef typename Traits<This>::SecondMoment SecondMoment;
    typedef typename Traits<This>::DynamicsMatrix DynamicsMatrix;

    using Traits<This>::GaussianBase::mean;
    using Traits<This>::GaussianBase::covariance;
    using Traits<This>::GaussianBase::dimension;
    using Traits<This>::GaussianBase::square_root;

public:
    LinearGaussianProcessModel(
            const SecondMoment& noise_covariance,
            const int dimension = DimensionOf<State>()):
        Traits<This>::GaussianBase(dimension),
        A_(DynamicsMatrix::Identity(dimension, dimension)),
        delta_time_(1.)
    {
        assert(dimension > 0);

        covariance(noise_covariance);
    }

    ~LinearGaussianProcessModel() { }

    virtual State predict_state(double delta_time,
                                const State& state,
                                const Noise& noise,
                                const Input& input)
    {
        condition(delta_time, state, input);

        return map_standard_normal(noise);
    }

    virtual size_t state_dimension() const
    {
        return Traits<This>::GaussianBase::dimension();
    }

    virtual size_t noise_dimension() const
    {
        return Traits<This>::GaussianBase::dimension();
    }

    virtual size_t input_dimension() const
    {
        return DimensionOf<Input>();
    }

    virtual void condition(const double& delta_time,
                           const State& x,
                           const Input& u = Input())
    {
        delta_time_ = delta_time;

        mean(A_ * x);
    }

    virtual State map_standard_normal(const Noise& sample) const
    {
        return mean() + delta_time_ * square_root() * sample;
    }

    virtual const DynamicsMatrix& A() const
    {
        return A_;
    }

    virtual void A(const DynamicsMatrix& dynamics_matrix)
    {
        A_ = dynamics_matrix;
    }

protected:
    DynamicsMatrix A_;
    double delta_time_;
};

}

#endif
<commit_msg>Added second constructor to initialize the model with the identity matrix as a the default covariance<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file linear_process_model.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__MODEL__PROCESS__LINEAR_GAUSSIAN_PROCESS_MODEL_HPP
#define FL__MODEL__PROCESS__LINEAR_GAUSSIAN_PROCESS_MODEL_HPP

#include <fl/util/traits.hpp>
#include <fl/distribution/gaussian.hpp>
#include <fl/model/process/process_model_interface.hpp>

namespace fl
{

// Forward declarations
template <typename State, typename Input_> class LinearGaussianProcessModel;

/**
 * Linear Gaussian process model traits. This trait definition contains all
 * types used internally within the linear model. Additionally, it provides the
 * types needed externally to use the model.
 */
template <typename State_, typename Input_>
struct Traits<LinearGaussianProcessModel<State_, Input_>>
{
    typedef Gaussian<State_> GaussianBase;

    typedef State_ State;
    typedef Input_ Input;
    typedef typename Traits<GaussianBase>::Scalar Scalar;
    typedef typename Traits<GaussianBase>::SecondMoment SecondMoment;
    typedef typename Traits<GaussianBase>::StandardVariate Noise;

    typedef ProcessModelInterface<State, Noise, Input> ProcessModelBase;

    typedef Eigen::Matrix<Scalar,
                          State::SizeAtCompileTime,
                          State::SizeAtCompileTime> DynamicsMatrix;
};

/**
 * \ingroup process_models
 * \todo correct input parameter
 */
template <typename State_, typename Input_ = Eigen::Matrix<double, 1, 1>>
class LinearGaussianProcessModel:
    public Traits<LinearGaussianProcessModel<State_, Input_>>::ProcessModelBase,
    public Traits<LinearGaussianProcessModel<State_, Input_>>::GaussianBase
{
public:
    typedef LinearGaussianProcessModel<State_, Input_> This;

    typedef typename Traits<This>::State State;
    typedef typename Traits<This>::Input Input;
    typedef typename Traits<This>::Noise Noise;
    typedef typename Traits<This>::Scalar Scalar;
    typedef typename Traits<This>::SecondMoment SecondMoment;
    typedef typename Traits<This>::DynamicsMatrix DynamicsMatrix;

    using Traits<This>::GaussianBase::mean;
    using Traits<This>::GaussianBase::covariance;
    using Traits<This>::GaussianBase::dimension;
    using Traits<This>::GaussianBase::square_root;

public:
    explicit
    LinearGaussianProcessModel(const SecondMoment& noise_covariance,
                               int dim = DimensionOf<State>()):
        Traits<This>::GaussianBase(dim),
        A_(DynamicsMatrix::Identity(dim, dim)),
        delta_time_(1.)
    {
        assert(dim > 0);

        covariance(noise_covariance);
    }

    explicit
    LinearGaussianProcessModel(int dim = DimensionOf<State>())
        : Traits<This>::GaussianBase(dim),
          A_(DynamicsMatrix::Identity(dim, dim)),
          delta_time_(1.)
    {
        assert(dim > 0);

        covariance(SecondMoment::Identity(dim, dim));
    }

    ~LinearGaussianProcessModel() { }

    virtual State predict_state(double delta_time,
                                const State& state,
                                const Noise& noise,
                                const Input& input)
    {
        condition(delta_time, state, input);

        return map_standard_normal(noise);
    }

    virtual size_t state_dimension() const
    {
        return Traits<This>::GaussianBase::dimension();
    }

    virtual size_t noise_dimension() const
    {
        return Traits<This>::GaussianBase::dimension();
    }

    virtual size_t input_dimension() const
    {
        return DimensionOf<Input>();
    }

    virtual void condition(const double& delta_time,
                           const State& x,
                           const Input& u = Input())
    {
        delta_time_ = delta_time;

        mean(A_ * x);
    }

    virtual State map_standard_normal(const Noise& sample) const
    {
        return mean() + delta_time_ * square_root() * sample;
    }

    virtual const DynamicsMatrix& A() const
    {
        return A_;
    }

    virtual void A(const DynamicsMatrix& dynamics_matrix)
    {
        A_ = dynamics_matrix;
    }

protected:
    DynamicsMatrix A_;
    double delta_time_;
};

}

#endif
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * 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
 *
 *****************************************************************************/

#ifndef MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
#define MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP

// mapnik
#include <mapnik/global.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/feature_kv_iterator.hpp>

// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/cons.hpp>

namespace boost { namespace spirit { namespace traits {

template <>
struct is_container<mapnik::Feature const> : mpl::false_ {} ;

template <>
struct container_iterator<mapnik::Feature const>
{
    typedef mapnik::feature_kv_iterator2 type;
};

template <>
struct begin_container<mapnik::Feature const>
{
    static mapnik::feature_kv_iterator2
    call (mapnik::Feature const& f)
    {
        return mapnik::feature_kv_iterator2(mapnik::value_not_null(),f.begin(),f.end());
    }
};

template <>
struct end_container<mapnik::Feature const>
{
    static mapnik::feature_kv_iterator2
    call (mapnik::Feature const& f)
    {
        return mapnik::feature_kv_iterator2(mapnik::value_not_null(),f.end(),f.end());
    }
};

template <>
struct transform_attribute<const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>,
                           mapnik::geometry_container const& ,karma::domain>
{
    typedef mapnik::geometry_container const& type;
    static type pre(const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>& f)
    {
        return boost::fusion::at<mpl::int_<0> >(f).paths();
    }
};

}}}

namespace mapnik { namespace json {

namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;

struct get_id
{
    template <typename T>
    struct result { typedef int type; };

    int operator() (mapnik::Feature const& f) const
    {
        return f.id();
    }
};

struct make_properties_range
{
    typedef boost::iterator_range<mapnik::feature_kv_iterator> properties_range_type;

    template <typename T>
    struct result { typedef properties_range_type type; };

    properties_range_type operator() (mapnik::Feature const& f) const
    {
        return boost::make_iterator_range(f.begin(),f.end());
    }
};

struct utf8
{
    template <typename T>
    struct result { typedef std::string type; };

    std::string operator() (UnicodeString const& ustr) const
    {
        std::string result;
        to_utf8(ustr,result);
        return result;
    }
};

struct value_base
{
    template <typename T>
    struct result { typedef mapnik::value_base const& type; };

    mapnik::value_base const& operator() (mapnik::value const& val) const
    {
        return val.base();
    }
};

template <typename OutputIterator>
struct escaped_string
    : karma::grammar<OutputIterator, std::string(char const*)>
{
    escaped_string()
        : escaped_string::base_type(esc_str)
    {
        using boost::spirit::karma::maxwidth;
        using boost::spirit::karma::right_align;

        esc_char.add('\a', "\\a")('\b', "\\b")('\f', "\\f")('\n', "\\n")
            ('\r', "\\r")('\t', "\\t")('\v', "\\v")('\\', "\\\\")
            ('\'', "\\\'")('\"', "\\\"")
            ;

        esc_str =   karma::lit(karma::_r1)
            << *(esc_char
                 | karma::print
                 | "\\u" << right_align(4,karma::lit('0'))[karma::hex])
            <<  karma::lit(karma::_r1)
            ;
    }

    karma::rule<OutputIterator, std::string(char const*)> esc_str;
    karma::symbols<char, char const*> esc_char;

};

template <typename OutputIterator>
struct feature_generator_grammar:
        karma::grammar<OutputIterator, mapnik::Feature const&()>
{
    typedef boost::tuple<std::string, mapnik::value> pair_type;
    typedef make_properties_range::properties_range_type range_type;

    feature_generator_grammar()
        : feature_generator_grammar::base_type(feature)
        , quote_("\"")

    {
        using boost::spirit::karma::lit;
        using boost::spirit::karma::uint_;
        using boost::spirit::karma::bool_;
        using boost::spirit::karma::int_;
        using boost::spirit::karma::double_;
        using boost::spirit::karma::_val;
        using boost::spirit::karma::_1;
        using boost::spirit::karma::_r1;
        using boost::spirit::karma::string;
        using boost::spirit::karma::eps;

        feature = lit("{\"type\":\"Feature\",\"id\":")
            << uint_[_1 = id_(_val)]
            << lit(",\"geometry\":") << geometry
            << lit(",\"properties\":") << properties
            << lit('}')
            ;

        properties = lit('{')
            << -(pair % lit(','))
            << lit('}')
            ;

        pair = lit('"')
            << string[_1 = phoenix::at_c<0>(_val)] << lit('"')
            << lit(':')
            << value(phoenix::at_c<1>(_val))
            ;

        value = (value_null_| bool_ | int_| double_ | ustring)[_1 = value_base_(_r1)]
            ;

        value_null_ = string[_1 = "null"]
            ;

        ustring = escaped_string_(quote_.c_str())[_1 = utf8_(_val)]
            ;
    }

    // rules
    karma::rule<OutputIterator, mapnik::Feature const&()> feature;
    multi_geometry_generator_grammar<OutputIterator> geometry;
    escaped_string<OutputIterator> escaped_string_;
    karma::rule<OutputIterator, mapnik::Feature const&()> properties;
    karma::rule<OutputIterator, pair_type()> pair;
    karma::rule<OutputIterator, void(mapnik::value const&)> value;
    karma::rule<OutputIterator, mapnik::value_null()> value_null_;
    karma::rule<OutputIterator, UnicodeString()> ustring;
    // phoenix functions
    phoenix::function<get_id> id_;
    phoenix::function<value_base> value_base_;
    phoenix::function<utf8> utf8_;
    std::string quote_;
};

}}

#endif // MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
<commit_msg>json generator: fix escape chars as per json spec, which is a subset of c/c++<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * 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
 *
 *****************************************************************************/

#ifndef MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
#define MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP

// mapnik
#include <mapnik/global.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <mapnik/feature_kv_iterator.hpp>

// boost
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/cons.hpp>

namespace boost { namespace spirit { namespace traits {

template <>
struct is_container<mapnik::Feature const> : mpl::false_ {} ;

template <>
struct container_iterator<mapnik::Feature const>
{
    typedef mapnik::feature_kv_iterator2 type;
};

template <>
struct begin_container<mapnik::Feature const>
{
    static mapnik::feature_kv_iterator2
    call (mapnik::Feature const& f)
    {
        return mapnik::feature_kv_iterator2(mapnik::value_not_null(),f.begin(),f.end());
    }
};

template <>
struct end_container<mapnik::Feature const>
{
    static mapnik::feature_kv_iterator2
    call (mapnik::Feature const& f)
    {
        return mapnik::feature_kv_iterator2(mapnik::value_not_null(),f.end(),f.end());
    }
};

template <>
struct transform_attribute<const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>,
                           mapnik::geometry_container const& ,karma::domain>
{
    typedef mapnik::geometry_container const& type;
    static type pre(const boost::fusion::cons<mapnik::feature_impl const&, boost::fusion::nil>& f)
    {
        return boost::fusion::at<mpl::int_<0> >(f).paths();
    }
};

}}}

namespace mapnik { namespace json {

namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;

struct get_id
{
    template <typename T>
    struct result { typedef int type; };

    int operator() (mapnik::Feature const& f) const
    {
        return f.id();
    }
};

struct make_properties_range
{
    typedef boost::iterator_range<mapnik::feature_kv_iterator> properties_range_type;

    template <typename T>
    struct result { typedef properties_range_type type; };

    properties_range_type operator() (mapnik::Feature const& f) const
    {
        return boost::make_iterator_range(f.begin(),f.end());
    }
};

struct utf8
{
    template <typename T>
    struct result { typedef std::string type; };

    std::string operator() (UnicodeString const& ustr) const
    {
        std::string result;
        to_utf8(ustr,result);
        return result;
    }
};

struct value_base
{
    template <typename T>
    struct result { typedef mapnik::value_base const& type; };

    mapnik::value_base const& operator() (mapnik::value const& val) const
    {
        return val.base();
    }
};

template <typename OutputIterator>
struct escaped_string
    : karma::grammar<OutputIterator, std::string(char const*)>
{
    escaped_string()
        : escaped_string::base_type(esc_str)
    {
        using boost::spirit::karma::maxwidth;
        using boost::spirit::karma::right_align;

        esc_char.add
            ('"', "\\\"")
            ('\\', "\\\\")
            ('\b', "\\b")
            ('\f', "\\f")
            ('\n', "\\n")
            ('\r', "\\r")
            ('\t', "\\t")
            ;

        esc_str =   karma::lit(karma::_r1)
            << *(esc_char
                 | karma::print
                 | "\\u" << right_align(4,karma::lit('0'))[karma::hex])
            <<  karma::lit(karma::_r1)
            ;
    }

    karma::rule<OutputIterator, std::string(char const*)> esc_str;
    karma::symbols<char, char const*> esc_char;

};

template <typename OutputIterator>
struct feature_generator_grammar:
        karma::grammar<OutputIterator, mapnik::Feature const&()>
{
    typedef boost::tuple<std::string, mapnik::value> pair_type;
    typedef make_properties_range::properties_range_type range_type;

    feature_generator_grammar()
        : feature_generator_grammar::base_type(feature)
        , quote_("\"")

    {
        using boost::spirit::karma::lit;
        using boost::spirit::karma::uint_;
        using boost::spirit::karma::bool_;
        using boost::spirit::karma::int_;
        using boost::spirit::karma::double_;
        using boost::spirit::karma::_val;
        using boost::spirit::karma::_1;
        using boost::spirit::karma::_r1;
        using boost::spirit::karma::string;
        using boost::spirit::karma::eps;

        feature = lit("{\"type\":\"Feature\",\"id\":")
            << uint_[_1 = id_(_val)]
            << lit(",\"geometry\":") << geometry
            << lit(",\"properties\":") << properties
            << lit('}')
            ;

        properties = lit('{')
            << -(pair % lit(','))
            << lit('}')
            ;

        pair = lit('"')
            << string[_1 = phoenix::at_c<0>(_val)] << lit('"')
            << lit(':')
            << value(phoenix::at_c<1>(_val))
            ;

        value = (value_null_| bool_ | int_| double_ | ustring)[_1 = value_base_(_r1)]
            ;

        value_null_ = string[_1 = "null"]
            ;

        ustring = escaped_string_(quote_.c_str())[_1 = utf8_(_val)]
            ;
    }

    // rules
    karma::rule<OutputIterator, mapnik::Feature const&()> feature;
    multi_geometry_generator_grammar<OutputIterator> geometry;
    escaped_string<OutputIterator> escaped_string_;
    karma::rule<OutputIterator, mapnik::Feature const&()> properties;
    karma::rule<OutputIterator, pair_type()> pair;
    karma::rule<OutputIterator, void(mapnik::value const&)> value;
    karma::rule<OutputIterator, mapnik::value_null()> value_null_;
    karma::rule<OutputIterator, UnicodeString()> ustring;
    // phoenix functions
    phoenix::function<get_id> id_;
    phoenix::function<value_base> value_base_;
    phoenix::function<utf8> utf8_;
    std::string quote_;
};

}}

#endif // MAPNIK_JSON_FEATURE_GENERATOR_GRAMMAR_HPP
<|endoftext|>