<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 <windows.h>
#include <commctrl.h>
#include "base/command_line.h"
#include "base/event_recorder.h"
#include "base/gfx/native_theme.h"
#include "base/resource_util.h"
#include "base/win_util.h"
#include "webkit/tools/test_shell/foreground_helper.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_platform_delegate.h"

TestShellPlatformDelegate::TestShellPlatformDelegate(
    const CommandLine& command_line)
    : command_line_(command_line) {
#ifdef _CRTDBG_MAP_ALLOC
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
#endif
}

TestShellPlatformDelegate::~TestShellPlatformDelegate() {
#ifdef _CRTDBG_MAP_ALLOC
  _CrtDumpMemoryLeaks();
#endif
}

void TestShellPlatformDelegate::PreflightArgs(int *argc, char ***argv) {
}

// This test approximates whether you have the Windows XP theme selected by
// inspecting a couple of metrics. It does not catch all cases, but it does
// pick up on classic vs xp, and normal vs large fonts. Something it misses
// is changes to the color scheme (which will infact cause pixel test
// failures).
//
// ** Expected dependencies **
// + Theme: Windows XP
// + Color scheme: Default (blue)
// + Font size: Normal
// + Font smoothing: off (minor impact).
//
static bool HasLayoutTestThemeDependenciesWin() {
  // This metric will be 17 when font size is "Normal". The size of drop-down
  // menus depends on it.
  if (::GetSystemMetrics(SM_CXVSCROLL) != 17)
    return false;

  // Check that the system fonts RenderThemeWin relies on are Tahoma 11 pt.
  NONCLIENTMETRICS metrics;
  win_util::GetNonClientMetrics(&metrics);
  LOGFONTW* system_fonts[] =
  { &metrics.lfStatusFont, &metrics.lfMenuFont, &metrics.lfSmCaptionFont };

  for (size_t i = 0; i < arraysize(system_fonts); ++i) {
    if (system_fonts[i]->lfHeight != -11 ||
        0 != wcscmp(L"Tahoma", system_fonts[i]->lfFaceName))
      return false;
  }
  return true;
}

bool TestShellPlatformDelegate::CheckLayoutTestSystemDependencies() {
  bool has_deps = HasLayoutTestThemeDependenciesWin();
  if (!has_deps) {
    fprintf(stderr,
            "\n"
            "###############################################################\n"
            "## Layout test system dependencies check failed.\n"
            "## Some layout tests may fail due to unexpected theme.\n"
            "##\n"
            "## To fix, go to Display Properties -> Appearance, and select:\n"
            "##  + Windows and buttons: Windows XP style\n"
            "##  + Color scheme: Default (blue)\n"
            "##  + Font size: Normal\n"
            "###############################################################\n");
  }
  return has_deps;
}

void TestShellPlatformDelegate::SuppressErrorReporting() {
  _set_abort_behavior(0, _WRITE_ABORT_MSG);
}

void TestShellPlatformDelegate::InitializeGUI() {
  INITCOMMONCONTROLSEX InitCtrlEx;

  InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
  InitCommonControlsEx(&InitCtrlEx);
  TestShell::RegisterWindowClass();
}

void TestShellPlatformDelegate::SelectUnifiedTheme() {
  gfx::NativeTheme::instance()->DisableTheming();
}

void TestShellPlatformDelegate::SetWindowPositionForRecording(
    TestShell *shell) {
  // Move the window to the upper left corner for consistent
  // record/playback mode.  For automation, we want this to work
  // on build systems where the script invoking us is a background
  // process.  So for this case, make our window the topmost window
  // as well.
  ForegroundHelper::SetForeground(shell->mainWnd());
  ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
}
<commit_msg>redo CL 21368 - fix test shell on windows to accept vista sys deps<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 <string>
#include <list>
#include <windows.h>
#include <commctrl.h>
#include "base/command_line.h"
#include "base/event_recorder.h"
#include "base/gfx/native_theme.h"
#include "base/resource_util.h"
#include "base/win_util.h"
#include "webkit/tools/test_shell/foreground_helper.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_platform_delegate.h"

TestShellPlatformDelegate::TestShellPlatformDelegate(
    const CommandLine& command_line)
    : command_line_(command_line) {
#ifdef _CRTDBG_MAP_ALLOC
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
#endif
}

TestShellPlatformDelegate::~TestShellPlatformDelegate() {
#ifdef _CRTDBG_MAP_ALLOC
  _CrtDumpMemoryLeaks();
#endif
}

void TestShellPlatformDelegate::PreflightArgs(int *argc, char ***argv) {
}

// This test approximates whether you are running the default themes for
// your platform by inspecting a couple of metrics.
// It does not catch all cases, but it does pick up on classic vs xp,
// and normal vs large fonts. Something it misses is changes to the color
// scheme (which will infact cause pixel test failures).
bool TestShellPlatformDelegate::CheckLayoutTestSystemDependencies() {
  std::list<std::string> errors;

  OSVERSIONINFOEX osvi;
  ::ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  ::GetVersionEx((OSVERSIONINFO *)&osvi);

  // default to XP metrics, override if on Vista
  int requiredVScrollSize = 17;
  int requiredFontSize = -11; // 8 pt
  const WCHAR *requiredFont = L"Tahoma";
  bool isVista = false;
  if (osvi.dwMajorVersion == 6
      && osvi.dwMinorVersion == 0
      && osvi.wProductType == VER_NT_WORKSTATION) {
    requiredFont = L"Segoe UI";
    requiredFontSize = -12; // 9 pt
    isVista = true;
  } else if (osvi.dwMajorVersion == 5
             && osvi.dwMinorVersion == 1
             && osvi.wProductType == VER_NT_WORKSTATION) {
    // XP;
  } else {
    errors.push_back("Unsupported Operating System version "
                     "(must use XP or Vista)");
  }

  // on both XP and Vista, this metric will be 17 when font size is "Normal".
  // The size of drop-down menus depends on it.
  int vScrollSize = ::GetSystemMetrics(SM_CXVSCROLL);
  if (vScrollSize != requiredVScrollSize) {
    errors.push_back("Must use normal size fonts (96 dpi)");
  }

  // font smoothing (including ClearType) must be disabled
  BOOL bFontSmoothing;
  SystemParametersInfo(SPI_GETFONTSMOOTHING, (UINT)0,
                       (PVOID)&bFontSmoothing, (UINT)0);
  if (bFontSmoothing) {
    errors.push_back("Font smoothing (ClearType) must be disabled");
  }

  // Check that we're using the default system fonts
  NONCLIENTMETRICS metrics;
  win_util::GetNonClientMetrics(&metrics);
  LOGFONTW* system_fonts[] =
  { &metrics.lfStatusFont, &metrics.lfMenuFont, &metrics.lfSmCaptionFont };

  for (size_t i = 0; i < arraysize(system_fonts); ++i) {
    if (system_fonts[i]->lfHeight != requiredFontSize ||
        wcscmp(requiredFont, system_fonts[i]->lfFaceName)) {
      if (isVista)
        errors.push_back("Must use either the Aero or Basic theme");
      else
        errors.push_back("Must use the default XP theme (Luna)");
      break;
    }
  }

  if (!errors.empty()) {
    fprintf(stderr, "%s",
      "##################################################################\n"
      "## Layout test system dependencies check failed.\n"
      "##\n");
    for (std::list<std::string>::iterator it = errors.begin();
         it != errors.end();
         ++it) {
      fprintf(stderr, "## %s\n", it->c_str());
    }
    fprintf(stderr, "%s",
      "##\n"
      "##################################################################\n");
  }
  return errors.empty();
}

void TestShellPlatformDelegate::SuppressErrorReporting() {
  _set_abort_behavior(0, _WRITE_ABORT_MSG);
}

void TestShellPlatformDelegate::InitializeGUI() {
  INITCOMMONCONTROLSEX InitCtrlEx;

  InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
  InitCommonControlsEx(&InitCtrlEx);
  TestShell::RegisterWindowClass();
}

void TestShellPlatformDelegate::SelectUnifiedTheme() {
  gfx::NativeTheme::instance()->DisableTheming();
}

void TestShellPlatformDelegate::SetWindowPositionForRecording(
    TestShell *shell) {
  // Move the window to the upper left corner for consistent
  // record/playback mode.  For automation, we want this to work
  // on build systems where the script invoking us is a background
  // process.  So for this case, make our window the topmost window
  // as well.
  ForegroundHelper::SetForeground(shell->mainWnd());
  ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
}
<|endoftext|>


<commit_before>// Copyright 2018-2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "GLFWOSPRayWindow.h"
#include "example_common.h"

using namespace ospray;
using rkcommon::make_unique;

int main(int argc, const char *argv[])
{
  bool denoiser = ospLoadModule("denoiser") == OSP_NO_ERROR;

  initializeOSPRay(argc, argv);

  auto glfwOSPRayWindow =
      make_unique<GLFWOSPRayWindow>(vec2i(1024, 768), denoiser);
  glfwOSPRayWindow->mainLoop();
  glfwOSPRayWindow.reset();

  ospShutdown();

  return 0;
}
<commit_msg>Load the denoiser module after initializing OSPRay<commit_after>// Copyright 2018-2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "GLFWOSPRayWindow.h"
#include "example_common.h"

using namespace ospray;
using rkcommon::make_unique;

int main(int argc, const char *argv[])
{
  initializeOSPRay(argc, argv);

  bool denoiser = ospLoadModule("denoiser") == OSP_NO_ERROR;

  auto glfwOSPRayWindow =
      make_unique<GLFWOSPRayWindow>(vec2i(1024, 768), denoiser);
  glfwOSPRayWindow->mainLoop();
  glfwOSPRayWindow.reset();

  ospShutdown();

  return 0;
}
<|endoftext|>


<commit_before>/*
* This source file is part of ArkGameFrame
* For the latest info, see https://github.com/ArkGame
*
* Copyright (c) 2013-2018 ArkGame authors.
*
* 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 "AFCAccountModule.h"
#include "Server/Interface/AFINetServerModule.h"

bool AFCAccountModule::Init()
{
    mnRoleHallContainer = -3;
    mnConnectContainer = -1;

    m_pKernelModule = pPluginManager->FindModule<AFIKernelModule>();
    m_pElementInfoModule = pPluginManager->FindModule<AFIElementModule>();
    m_pUUIDModule = pPluginManager->FindModule<AFIGUIDModule>();

    //m_pEventProcessModule->AddEventCallBack(0, AFED_ON_DATABASE_SERVER_LOADROE_BEGIN, OnLoadRoleBeginEvent);
    //m_pEventProcessModule->AddEventCallBack(0, AFED_ON_DATABASE_SERVER_LOADROE_FINAL_RESULTS, OnLoadRoleFinalEvent);
    //m_pEventProcessModule->AddEventCallBack(0, AFED_ON_CLIENT_CREATEROLE, OnCreateRoleEvent);
    //m_pEventProcessModule->AddEventCallBack(0, AFED_ON_CLIENT_DELETEROLE, OnDeleteRoleEvent);
    //m_pEventProcessModule->AddEventCallBack(0, AFED_ON_CLIENT_LEAVE_GAME, OnAcountDisConnectEvent);

    return true;
}

bool AFCAccountModule::Shut()
{
    return true;
}

bool AFCAccountModule::Update()
{
    return true;
}

int AFCAccountModule::OnLoadRoleFinalEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    //if(9 != var.GetCount())
    //{
    //    return -1;
    //}

    ////赋予属性
    //const char* pstrAccount = var.StringVal(0);
    //AFCValueList valueInfo;
    //valueInfo << pstrAccount;

    //int nCount = 0;
    //for(int i = 1; i <= 7; i += 2)
    //{
    //    const char* pstrRoleName = var.StringVal(i);
    //    if(strlen(pstrRoleName) > 0)
    //    {
    //        //看容器中是否已经存在，存在则不创建
    //        AFCValueList varHallObjectList;
    //        AFCValueList varHalvalueInfo;
    //        varHalvalueInfo << pstrRoleName;
    //        int nHallObjectCount = m_pKernelModule->GetObjectByProperty(mnRoleHallContainer, "RoleName", varHalvalueInfo, varHallObjectList);
    //        if(nHallObjectCount > 0)
    //        {

    //            for(int j = 0; j < varHallObjectList.GetCount(); j++)
    //            {
    //                m_pKernelModule->LogErrorObject(varHallObjectList.ObjectVal(j));
    //                m_pKernelModule->DestroyObject(varHallObjectList.ObjectVal(j));
    //            }
    //        }

    //        GTProperty* gtPproperty = m_pElementInfoModule->GetPropertyManager("Scene0")->GetElement("RelivePos");
    //        const char* pstrRelivePos = gtPproperty->QueryString();
    //        AFCValueList valueRelivePos(pstrRelivePos, ",");

    //        char szConfigIindex[MAX_PATH] = { 0 };
    //        sprintf(szConfigIindex, "%d", var.IntVal(i + 1));

    //        AFCValueList arg;
    //        arg << "Account" << pstrAccount;
    //        arg << "RoleName" << pstrRoleName;
    //        arg << "SceneID" << mnRoleHallContainer;
    //        arg << "X" << atof(valueRelivePos.StringVal(0));
    //        arg << "Y" << atof(valueRelivePos.StringVal(1));
    //        arg << "Z" << atof(valueRelivePos.StringVal(2));
    //        m_pKernelModule->CreateObject(0, mnRoleHallContainer, 0, "Player", szConfigIindex, arg);

    //        nCount++;
    //    }
    //}

    //char szInfo[MAX_PATH] = { 0 };
    //sprintf(szInfo, "Load data final, %s: have %d role.", pstrAccount, nCount);
    //m_pKernelModule->LogInfo(szInfo);

    return 0;
}

bool AFCAccountModule::PostInit()
{
    //m_pKernelModule->CreateContainer(mnRoleHallContainer, "");

    //m_pKernelModule->LogInfo(" -3 RoleHallContainer ");

    return true;
}

bool AFCAccountModule::GetRoleList(const std::string& strAccount, AFMsg::AckRoleLiteInfoList& xAckRoleLiteInfoList)
{

    return true;
}

bool AFCAccountModule::CreateRole(const std::string& strAccount, AFMsg::AckRoleLiteInfoList& xAckRoleLiteInfoList, const AFIDataList& varList)
{
    AFMsg::RoleLiteInfo* pData = xAckRoleLiteInfoList.add_char_data();
    pData->mutable_id()->CopyFrom(AFINetModule::GUIDToPB(m_pUUIDModule->CreateGUID()));

    int nCareer = varList.Int(0);
    int sex = varList.Int(1);
    int race = varList.Int(2);
    std::string noob_name = varList.String(3);
    int game_id = varList.Int(4);

    pData->set_career(nCareer);
    pData->set_sex(sex);
    pData->set_race(race);
    pData->set_noob_name(noob_name);
    pData->set_game_id(game_id);
    pData->set_role_level(1);
    pData->set_delete_time(0);
    pData->set_reg_time(0);
    pData->set_last_offline_time(0);
    pData->set_last_offline_ip(0);
    pData->set_view_record("");

    return true;
}

bool AFCAccountModule::DeleteRole(const std::string& strAccount, AFMsg::AckRoleLiteInfoList& xAckRoleLiteInfoList)
{
    return true;
}

int AFCAccountModule::OnCreateRoleEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    //if(6 != var.GetCount())
    //{
    //    return 0;
    //}

    ////如果有4个玩家则不让创建
    //const char* pstrAccountName = var.StringVal(0);
    //const char* pstrRoleName = var.StringVal(1);
    //int nRoleSex = var.IntVal(2);
    //int nRoleJob = var.IntVal(3);
    //int nRoleRace = var.IntVal(4);
    //int nRoleCamp = var.IntVal(5);

    //AFCValueList roleLlist;
    //if(m_pNoSqlModule->QueryAccountRoleList(pstrAccountName, roleLlist) >= 4)
    //    //if (m_pDataBaseModule->QueryAccountRoleList(pstrAccountName, roleLlist) >= 4)
    //{
    //    return 0;
    //}
    ////////////////////////////////////////////////////////////////////////////
    ////创建人物直接走了数据库
    ////////////////////////////////////////////////////////////////////////////
    //if(m_pNoSqlModule->CreateRole(pstrAccountName, pstrRoleName) <= 0)
    //    //if (m_pDataBaseModule->CreateRole(pstrAccountName, pstrRoleName) <= 0)
    //{
    //    return 0;
    //}

    //AFCValueList varPropertyKeyList;
    //AFCValueList varPropertyValueList;

    //varPropertyKeyList << "RoleName"
    //                   << "Sex"
    //                   << "Job"
    //                   << "Race"
    //                   << "Camp"
    //                   << "SceneID"
    //                   << "LastContainerID"
    //                   << "ClassName";

    //varPropertyValueList << pstrRoleName
    //                     << nRoleSex
    //                     << nRoleJob
    //                     << nRoleRace
    //                     << nRoleCamp
    //                     << mnRoleHallContainer
    //                     << 1
    //                     << "Player";

    //int nConfigName = nRoleJob + nRoleSex * 10;
    //char szConfigName[MAX_PATH] = { 0 };
    //sprintf(szConfigName, "%d", nConfigName);

    ////弄到所有的属性
    //GTPropertyManager* pConfigPropertyManager = m_pElementInfoModule->GetPropertyManager(szConfigName);
    //if(pConfigPropertyManager)
    //{
    //    GTProperty* pConfigPropertyInfo = pConfigPropertyManager->First();
    //    while(pConfigPropertyInfo)
    //    {
    //        //看属性是否需要保存,不需要保存的就别村
    //        if(!pConfigPropertyInfo->GetSave())
    //        {
    //            pConfigPropertyInfo = pConfigPropertyManager->Next();
    //            continue;
    //        }
    //        //这个属性RoleName是玩家的，因此，这里不能有RoleName
    //        const AFIDataList& valueList = pConfigPropertyInfo->GetValue();

    //        if(0 != strcmp(pConfigPropertyInfo->GetKey(), "RoleName")
    //                && 0 != strcmp(pConfigPropertyInfo->GetKey(), "Sex")
    //                && 0 != strcmp(pConfigPropertyInfo->GetKey(), "Job")
    //                && 0 != strcmp(pConfigPropertyInfo->GetKey(), "Race")
    //                && 0 != strcmp(pConfigPropertyInfo->GetKey(), "Camp")
    //                && 0 != strcmp(pConfigPropertyInfo->GetKey(), "Account")
    //                && 0 != strcmp(pConfigPropertyInfo->GetKey(), "SceneID")
    //                && 0 != strcmp(pConfigPropertyInfo->GetKey(), "LastContainerID")
    //                && 0 != strcmp(pConfigPropertyInfo->GetKey(), "ClassName"))
    //        {
    //            varPropertyKeyList << pConfigPropertyInfo->GetKey();
    //            varPropertyValueList.Append(valueList, 0, 1);
    //        }

    //        pConfigPropertyInfo = pConfigPropertyManager->Next();
    //    }
    //}
    //varPropertyKeyList << "RoleName";
    //varPropertyValueList << pstrRoleName;
    //varPropertyKeyList << "Sex";
    //varPropertyValueList << nRoleSex;
    //varPropertyKeyList << "Job";
    //varPropertyValueList << nRoleJob;
    //varPropertyKeyList << "Race";
    //varPropertyValueList << nRoleRace;
    //varPropertyKeyList << "Camp";
    //varPropertyValueList << nRoleCamp;
    //varPropertyKeyList << "SceneID";
    //varPropertyValueList << mnRoleHallContainer;
    //varPropertyKeyList << "LastContainerID";
    //varPropertyValueList << 1;//1号场景为新手村
    //varPropertyKeyList << "ClassName";
    //varPropertyValueList << "Player";
    //varPropertyKeyList << "Level";
    //varPropertyValueList << 1;

    //m_pNoSqlModule->SetRoleProperty(pstrRoleName, varPropertyKeyList, varPropertyValueList);

    ////////////////////////////////////////////////////////////////////////////
    //GTProperty* gtPproperty = m_pElementInfoModule->GetPropertyManager("Scene0")->GetElement("RelivePos");
    //const char* pstrRelivePos = gtPproperty->QueryString();
    //AFCValueList valueRelivePos(pstrRelivePos, ",");

    //AFCValueList arg;
    //arg << "Account" << pstrAccountName;
    //arg << "RoleName" << pstrRoleName;
    //arg << "SceneID" << mnRoleHallContainer;
    //arg << "X" << atof(valueRelivePos.StringVal(0));
    //arg << "Y" << atof(valueRelivePos.StringVal(1));
    //arg << "Z" << atof(valueRelivePos.StringVal(2));
    //m_pKernelModule->CreateObject(0, mnRoleHallContainer, 0, "Player", szConfigName, arg);
    ////nosql 则不需要这样了
    ////m_pEventProcessModule->DoEvent(0, AFED_ON_DATABASE_SERVER_LOADROE_BEGIN, AFCValueList() << pstrAccountName);

    return 0;
}

int AFCAccountModule::OnDeleteRoleEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    //if(2 != var.GetCount())
    //{
    //    return 0;
    //}

    //const char* pstrAccountName = var.StringVal(0);
    //const char* pstrRoleName = var.StringVal(1);

    //AFCValueList valObjctList;
    //m_pKernelModule->GetObjectByProperty(mnRoleHallContainer, "RoleName", AFCValueList() << pstrRoleName, valObjctList);
    //if(valObjctList.GetCount() == 1)
    //{
    //    m_pNoSqlModule->DeleteRole(pstrAccountName, pstrRoleName);
    //    //m_pDataBaseModule->DeleteRole(pstrAccountName, pstrRoleName);
    //    m_pKernelModule->DestroyObject(valObjctList.ObjectVal(0));
    //    //m_pEventProcessModule->DoEvent( 0, AFED_ON_CLIENT_DELETEROLE_RESULTS, AFCValueList() << pstrAccountName << pstrRoleName );
    //}

    return 0;
}

int AFCAccountModule::OnAcountDisConnectEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    /*   if(var.GetCount() == 3)
       {
           const char* pstrAccount = var.StringVal(0);
           const char* pstrRoleName = var.StringVal(1);
           AFGUID ident = var.ObjectVal(2);

           if(strlen(pstrAccount) > 0)
           {
               if(m_pGameLogicModule->GetGameID() == 1)
               {

                   if(!ident.IsNull())
                   {
                       m_pKernelModule->DestroyObject(ident);
                   }
                   else
                   {
                       AFCValueList varHallObjectList;
                       AFCValueList varHalvalueInfo;
                       varHalvalueInfo << pstrAccount;

                       int nHallObjectCount = m_pKernelModule->GetObjectByProperty(mnRoleHallContainer, "Account", varHalvalueInfo, varHallObjectList);
                       for(int i  = 0; i < varHallObjectList.GetCount(); i++)
                       {
                           AFGUID identHall = varHallObjectList.ObjectVal(i);
                           if(ident.nSerial == m_pGameLogicModule->GetGameID()
                                   && m_pKernelModule->GetObject(identHall))
                           {
                               m_pKernelModule->DestroyObject(identHall);
                           }
                       }
                   }
               }
           }
       }
    */
    return 0;
}

int AFCAccountModule::OnLoadRoleBeginEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    ////直接从NOSQL数据库拉
    //const char* pstrAccount = var.StringVal(0);
    //AFCValueList roleLlist;
    //if(m_pNoSqlModule->QueryAccountRoleList(pstrAccount, roleLlist) > 0)
    //{
    //    for(int i = 0; i < roleLlist.GetCount(); i++)
    //    {
    //        const char* pstrRoleName = roleLlist.StringVal(i);
    //        if(strlen(pstrRoleName) > 0)
    //        {
    //            //看容器中是否已经存在，存在则不创建
    //            AFCValueList varHallObjectList;
    //            AFCValueList varHalvalueInfo;
    //            varHalvalueInfo << pstrRoleName;
    //            int nHallObjectCount = m_pKernelModule->GetObjectByProperty(mnRoleHallContainer, "RoleName", varHalvalueInfo, varHallObjectList);
    //            if(nHallObjectCount > 0)
    //            {
    //                for(int j = 0; j < varHallObjectList.GetCount(); j++)
    //                {
    //                    m_pKernelModule->LogErrorObject(varHallObjectList.ObjectVal(j));
    //                    m_pKernelModule->DestroyObject(varHallObjectList.ObjectVal(j));
    //                }
    //            }

    //            GTProperty* gtPproperty = m_pElementInfoModule->GetPropertyManager("Scene0")->GetElement("RelivePos");
    //            const char* pstrRelivePos = gtPproperty->QueryString();
    //            AFCValueList valueRelivePos(pstrRelivePos, ",");

    //            char szConfigIindex[MAX_PATH] = { 0 };
    //            sprintf(szConfigIindex, "%d", var.IntVal(i + 1));

    //            AFCValueList arg;
    //            arg << "Account" << pstrAccount;
    //            arg << "RoleName" << pstrRoleName;
    //            arg << "SceneID" << mnRoleHallContainer;
    //            arg << "X" << atof(valueRelivePos.StringVal(0));
    //            arg << "Y" << atof(valueRelivePos.StringVal(1));
    //            arg << "Z" << atof(valueRelivePos.StringVal(2));
    //            m_pKernelModule->CreateObject(0, mnRoleHallContainer, 0, "Player", szConfigIindex, arg);
    //        }
    //    }
    //}

    return 0;
}

<commit_msg>fix sonar bug<commit_after>/*
* This source file is part of ArkGameFrame
* For the latest info, see https://github.com/ArkGame
*
* Copyright (c) 2013-2018 ArkGame authors.
*
* 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 "AFCAccountModule.h"
#include "Server/Interface/AFINetServerModule.h"

bool AFCAccountModule::Init()
{
    mnRoleHallContainer = -3;
    mnConnectContainer = -1;

    m_pKernelModule = pPluginManager->FindModule<AFIKernelModule>();
    m_pElementInfoModule = pPluginManager->FindModule<AFIElementModule>();
    m_pUUIDModule = pPluginManager->FindModule<AFIGUIDModule>();
    return true;
}

bool AFCAccountModule::Shut()
{
    return true;
}

bool AFCAccountModule::Update()
{
    return true;
}

int AFCAccountModule::OnLoadRoleFinalEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    return 0;
}

bool AFCAccountModule::PostInit()
{
    return true;
}

bool AFCAccountModule::GetRoleList(const std::string& strAccount, AFMsg::AckRoleLiteInfoList& xAckRoleLiteInfoList)
{

    return true;
}

bool AFCAccountModule::CreateRole(const std::string& strAccount, AFMsg::AckRoleLiteInfoList& xAckRoleLiteInfoList, const AFIDataList& varList)
{
    AFMsg::RoleLiteInfo* pData = xAckRoleLiteInfoList.add_char_data();
    pData->mutable_id()->CopyFrom(AFINetModule::GUIDToPB(m_pUUIDModule->CreateGUID()));

    int nCareer = varList.Int(0);
    int sex = varList.Int(1);
    int race = varList.Int(2);
    std::string noob_name = varList.String(3);
    int game_id = varList.Int(4);

    pData->set_career(nCareer);
    pData->set_sex(sex);
    pData->set_race(race);
    pData->set_noob_name(noob_name);
    pData->set_game_id(game_id);
    pData->set_role_level(1);
    pData->set_delete_time(0);
    pData->set_reg_time(0);
    pData->set_last_offline_time(0);
    pData->set_last_offline_ip(0);
    pData->set_view_record("");

    return true;
}

bool AFCAccountModule::DeleteRole(const std::string& strAccount, AFMsg::AckRoleLiteInfoList& xAckRoleLiteInfoList)
{
    return true;
}

int AFCAccountModule::OnCreateRoleEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    return 0;
}

int AFCAccountModule::OnDeleteRoleEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    return 0;
}

int AFCAccountModule::OnAcountDisConnectEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    return 0;
}

int AFCAccountModule::OnLoadRoleBeginEvent(const AFGUID& object, const int nEventID, const AFIDataList& var)
{
    return 0;
}

<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
// PSP Player Emulation Suite
// Copyright (C) 2006 Ben Vanik (noxa)
// Licensed under the LGPL - see License.txt in the project root for details
// ----------------------------------------------------------------------------

#include "StdAfx.h"
#include "R4000Generator.h"
#include "R4000Cpu.h"
#include "R4000Core.h"
#include "R4000Memory.h"
#include "R4000GenContext.h"

#include "Loader.hpp"
#include "CodeGenerator.hpp"

using namespace System::Diagnostics;
using namespace Noxa::Emulation::Psp;
using namespace Noxa::Emulation::Psp::Cpu;
using namespace SoftWire;

#define g context->Generator

GenerationResult SYSCALL( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult BREAK( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult SYNC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult COP1( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, ushort imm )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult COP2( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, ushort imm )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult HALT( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult MFIC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult MTIC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}
<commit_msg>The code I had forgot to checkin - special instructions besides SYSCALL (needs to be converted).<commit_after>// ----------------------------------------------------------------------------
// PSP Player Emulation Suite
// Copyright (C) 2006 Ben Vanik (noxa)
// Licensed under the LGPL - see License.txt in the project root for details
// ----------------------------------------------------------------------------

#include "StdAfx.h"
#include "R4000Generator.h"
#include "R4000Cpu.h"
#include "R4000Core.h"
#include "R4000Memory.h"
#include "R4000GenContext.h"

#include "Loader.hpp"
#include "CodeGenerator.hpp"

using namespace System::Diagnostics;
using namespace Noxa::Emulation::Psp;
using namespace Noxa::Emulation::Psp::Bios;
using namespace Noxa::Emulation::Psp::Cpu;
using namespace SoftWire;

#define g context->Generator

GenerationResult SYSCALL( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	int syscall = ( int )( ( code >> 6 ) & 0xFFFFF );

	BiosFunction^ biosFunction = context->Cpu->_syscalls[ syscall ];
	bool willCall;
	bool hasReturn;
	int paramCount;
	if( biosFunction != nullptr )
	{
		willCall = biosFunction->IsImplemented;
		hasReturn = biosFunction->HasReturn;
		paramCount = biosFunction->ParameterCount;

		if( biosFunction->IsImplemented == false )
		{
			if( pass == 0 )
			{
				Debug::WriteLine( String::Format( "R4000Generator: NID 0x{0:X8} {1} is not implemented",
					biosFunction->NID, biosFunction->Name ) );
			}
		}
	}
	else
	{
		willCall = false;
		hasReturn = false;
		paramCount = 0;

		if( pass == 0 )
			Debug::WriteLine( "R4000Generator: unregistered syscall attempt" );
	}
/*
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
		// It's important that we save what we think is the current PC
		// If we had an UpdatePc, it means a branch has updated it before us
		// and we need to save it - otherwise, save the PC following us
		context.ILGen.Emit( OpCodes.Ldarg_0 );
		if( context.UpdatePc == true )
			context.ILGen.Emit( OpCodes.Ldloc_2 );
		else
			context.ILGen.Emit( OpCodes.Ldc_I4, address + 4 );
		context.ILGen.Emit( OpCodes.Stfld, context.Core0Pc );

		if( willCall == true )
		{
			// Lame, but we need the object this gets called on and
			// there is no way to communicate what we know now to the final IL
			//context.Cpu._syscalls[ syscall ].Target.Target;
			context.ILGen.Emit( OpCodes.Ldarg_3 );
			context.ILGen.Emit( OpCodes.Ldc_I4, syscall );
			context.ILGen.Emit( OpCodes.Ldelem, typeof( BiosFunction ) );
			context.ILGen.Emit( OpCodes.Ldfld, context.BiosFunctionTarget );
			context.ILGen.Emit( OpCodes.Call, context.DelegateTargetGet );

			// Memory
			context.ILGen.Emit( OpCodes.Ldarg_1 );

			if( paramCount > 0 )
			{
				EmitLoadRegister( context, 4 );
				if( paramCount > 1 )
				{
					EmitLoadRegister( context, 5 );
					if( paramCount > 2 )
					{
						EmitLoadRegister( context, 6 );
						if( paramCount > 3 )
						{
							EmitLoadRegister( context, 7 );
							if( paramCount > 4 )
							{
								// Maybe this should always go?
								EmitLoadRegister( context, 29 );
							}
							else
								context.ILGen.Emit( OpCodes.Ldc_I4_0 );
						}
						else
						{
							context.ILGen.Emit( OpCodes.Ldc_I4_0 );
							context.ILGen.Emit( OpCodes.Ldc_I4_0 );
						}
					}
					else
					{
						context.ILGen.Emit( OpCodes.Ldc_I4_0 );
						context.ILGen.Emit( OpCodes.Ldc_I4_0 );
						context.ILGen.Emit( OpCodes.Ldc_I4_0 );
					}
				}
				else
				{
					context.ILGen.Emit( OpCodes.Ldc_I4_0 );
					context.ILGen.Emit( OpCodes.Ldc_I4_0 );
					context.ILGen.Emit( OpCodes.Ldc_I4_0 );
					context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				}
			}
			else
			{
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
				context.ILGen.Emit( OpCodes.Ldc_I4_0 );
			}

			if( biosFunction.Target.Method.IsFinal == true )
				context.ILGen.Emit( OpCodes.Call, biosFunction.Target.Method );
			else
				context.ILGen.Emit( OpCodes.Callvirt, biosFunction.Target.Method );

			// Function returns a value - may need to ignore
			if( hasReturn == true )
				EmitStoreRegister( context, 2 );
			else
				context.ILGen.Emit( OpCodes.Pop );
		}
		else
		{
			// When we fail, we need to make sure to handle the cases where
			// the method has a return or else things could get even worse!
			if( biosFunction != null )
			{
				if( hasReturn == true )
				{
					context.ILGen.Emit( OpCodes.Ldc_I4, -1 );
					EmitStoreRegister( context, 2 );
				}
			}
		}
	}*/
	return GenerationResult::Syscall;
}

GenerationResult BREAK( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: BREAK not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}

GenerationResult SYNC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	// pg 629 - not needed?
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: SYNC not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}

GenerationResult COP1( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, ushort imm )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult COP2( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, ushort imm )
{
	if( pass == 0 )
	{
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Invalid;
}

GenerationResult HALT( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: HALT not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}

GenerationResult MFIC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: MFIC not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}

GenerationResult MTIC( R4000GenContext^ context, int pass, int address, uint code, byte opcode, byte rs, byte rt, byte rd, byte shamt, byte function )
{
	if( pass == 0 )
	{
		Debug::WriteLine( "R4000Generator: MTIC not implemented" );
	}
	else if( pass == 1 )
	{
	}
	return GenerationResult::Success;
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2013 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreRoot.h"
#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreStringConverter.h"
#include "OgreWindowEventUtilities.h"

#include "OgreGLES2Prerequisites.h"
#include "OgreGLES2RenderSystem.h"

#include "OgreAndroidEGLSupport.h"
#include "OgreAndroidEGLWindow.h"
#include "OgreAndroidEGLContext.h"
#include "OgreAndroidResourceManager.h"

#include <iostream>
#include <algorithm>
#include <climits>

namespace Ogre {
	AndroidEGLWindow::AndroidEGLWindow(AndroidEGLSupport *glsupport)
		: EGLWindow(glsupport),
		  mMaxBufferSize(32),
		  mMinBufferSize(16),
		  mMaxDepthSize(16),
		  mMaxStencilSize(0),
		  mMSAA(0),
		  mCSAA(0)
	{
	}

	AndroidEGLWindow::~AndroidEGLWindow()
	{
	}

	EGLContext* AndroidEGLWindow::createEGLContext() const
	{
		return new AndroidEGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface);
	}

	void AndroidEGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height )
	{
		// We don't have a native window.... but I think all android windows are origined
		left = top = 0;
	}

	void AndroidEGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams)
	{
	}

	void AndroidEGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title )
	{
	}

	void AndroidEGLWindow::reposition( int left, int top )
	{
	}

	void AndroidEGLWindow::resize(uint width, uint height)
	{
	}

	void AndroidEGLWindow::windowMovedOrResized()
	{
        if(mActive)
        {
            eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, (EGLint*)&mWidth);
            eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, (EGLint*)&mHeight);

            // Notify viewports of resize
            ViewportList::iterator it = mViewportList.begin();
            while( it != mViewportList.end() )
                (*it++).second->_updateDimensions();
        }
	}

    void AndroidEGLWindow::switchFullScreen(bool fullscreen)
    {

    }

    void AndroidEGLWindow::create(const String& name, uint width, uint height,
                               bool fullScreen, const NameValuePairList *miscParams)
    {
		mName = name;
        mWidth = width;
        mHeight = height;
        mLeft = 0;
        mTop = 0;
        mIsFullScreen = fullScreen;
        void* eglContext = NULL;
        AConfiguration* config = NULL;

        if (miscParams)
        {
            NameValuePairList::const_iterator opt;
            NameValuePairList::const_iterator end = miscParams->end();

            if ((opt = miscParams->find("currentGLContext")) != end &&
                StringConverter::parseBool(opt->second))
            {
                eglContext = eglGetCurrentContext();
                if (eglContext)
                {
                    OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                                "currentGLContext was specified with no current GL context",
                                "EGLWindow::create");
                }

                eglContext = eglGetCurrentContext();
                mEglSurface = eglGetCurrentSurface(EGL_DRAW);
            }

            if((opt = miscParams->find("externalWindowHandle")) != end)
            {
                mWindow = (ANativeWindow*)(Ogre::StringConverter::parseInt(opt->second));
            }

            if((opt = miscParams->find("androidConfig")) != end)
            {
                config = (AConfiguration*)(Ogre::StringConverter::parseInt(opt->second));
            }

            int ctxHandle = -1;
            if((miscParams->find("externalGLContext")) != end)
            {
                mIsExternalGLControl = true;
                ctxHandle = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("maxColourBufferSize")) != end)
            {
                mMaxBufferSize = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("maxDepthBufferSize")) != end)
            {
                mMaxDepthSize = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("maxStencilBufferSize")) != end)
            {
                mMaxStencilSize = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("minColourBufferSize")) != end)
            {
                mMinBufferSize = Ogre::StringConverter::parseInt(opt->second);
                if (mMinBufferSize > mMaxBufferSize) mMinBufferSize = mMaxBufferSize;
            }

			if((opt = miscParams->find("MSAA")) != end)
            {
                mMSAA = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("CSAA")) != end)
            {
                mCSAA = Ogre::StringConverter::parseInt(opt->second);
            }
        }

        initNativeCreatedWindow(miscParams);

        if (mEglSurface)
        {
            mEglConfig = mGLSupport->getGLConfigFromDrawable (mEglSurface, &width, &height);
        }

        if (!mEglConfig && eglContext)
        {
            mEglConfig = mGLSupport->getGLConfigFromContext(eglContext);

            if (!mEglConfig)
            {
                // This should never happen.
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                            "Unexpected failure to determine a EGLFBConfig",
                            "EGLWindow::create");
            }
        }

        mIsExternal = (mEglSurface != 0);

        if (!mEglConfig)
        {
			_createInternalResources(mWindow, config);
            mHwGamma = false;
        }

        mContext = createEGLContext();
        mContext->setCurrent();

        eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, (EGLint*)&mWidth);
        eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, (EGLint*)&mHeight);
        EGL_CHECK_ERROR

		mActive = true;
		mVisible = true;
		mClosed = false;
	}

    void AndroidEGLWindow::_destroyInternalResources()
    {
        GLES2RenderSystem::getResourceManager()->notifyOnContextLost();
        mContext->_destroyInternalResources();

        eglDestroySurface(mEglDisplay, mEglSurface);
        EGL_CHECK_ERROR

        eglTerminate(mEglDisplay);
        EGL_CHECK_ERROR

        mEglDisplay = 0;
        mEglSurface = 0;

        mActive = false;
		mVisible = false;
        mClosed = true;
    }

    void AndroidEGLWindow::_createInternalResources(NativeWindowType window, AConfiguration* config)
    {
        mWindow = window;

        int minAttribs[] = {
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
            EGL_BUFFER_SIZE, mMinBufferSize,
            EGL_DEPTH_SIZE, 16,
            EGL_NONE
        };

        int maxAttribs[] = {
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
			EGL_BUFFER_SIZE, mMaxBufferSize,
            EGL_DEPTH_SIZE, mMaxDepthSize,
            EGL_STENCIL_SIZE, mMaxStencilSize,
            EGL_NONE
        };

		bool bAASuccess = false;
		if (mCSAA)
		{
			try
			{
				int CSAAminAttribs[] = {
					EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
					EGL_BUFFER_SIZE, mMinBufferSize,
					EGL_DEPTH_SIZE, 16,
					EGL_COVERAGE_BUFFERS_NV, 1,
					EGL_COVERAGE_SAMPLES_NV, mMSAA,
					EGL_NONE
				};
				int CSAAmaxAttribs[] = {
					EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
					EGL_BUFFER_SIZE, mMaxBufferSize,
					EGL_DEPTH_SIZE, mMaxDepthSize,
					EGL_STENCIL_SIZE, mMaxStencilSize,
					EGL_COVERAGE_BUFFERS_NV, 1,
					EGL_COVERAGE_SAMPLES_NV, mMSAA,
					EGL_NONE
				};
				mEglConfig = mGLSupport->selectGLConfig(CSAAminAttribs, CSAAmaxAttribs);
				bAASuccess = true;
			}
			catch (Exception& e)
			{
				LogManager::getSingleton().logMessage("AndroidEGLWindow::_createInternalResources: setting CSAA failed");
			}
		}

		if (mMSAA && !bAASuccess)
		{
			try
			{
				int MSAAminAttribs[] = {
					EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
					EGL_BUFFER_SIZE, mMinBufferSize,
					EGL_DEPTH_SIZE, 16,
					EGL_SAMPLE_BUFFERS, 1,
					EGL_SAMPLES, mMSAA,
					EGL_NONE
				};
				int MSAAmaxAttribs[] = {
					EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
					EGL_BUFFER_SIZE, mMaxBufferSize,
					EGL_DEPTH_SIZE, mMaxDepthSize,
					EGL_STENCIL_SIZE, mMaxStencilSize,
					EGL_SAMPLE_BUFFERS, 1,
					EGL_SAMPLES, mMSAA,
					EGL_NONE
				};
				mEglConfig = mGLSupport->selectGLConfig(MSAAminAttribs, MSAAmaxAttribs);
				bAASuccess = true;
			}
			catch (Exception& e)
			{
				LogManager::getSingleton().logMessage("AndroidEGLWindow::_createInternalResources: setting MSAA failed");
			}
		}

        mEglDisplay = mGLSupport->getGLDisplay();
        if (!bAASuccess) mEglConfig = mGLSupport->selectGLConfig(minAttribs, maxAttribs);

        EGLint format;
        eglGetConfigAttrib(mEglDisplay, mEglConfig, EGL_NATIVE_VISUAL_ID, &format);
        EGL_CHECK_ERROR

        ANativeWindow_setBuffersGeometry(mWindow, 0, 0, format);

        mEglSurface = createSurfaceFromWindow(mEglDisplay, mWindow);

        if(config)
        {
            bool isLandscape = (int)AConfiguration_getOrientation(config) == 2;
            mGLSupport->setConfigOption("Orientation", isLandscape ? "Landscape" : "Portrait");
        }

        if(mContext)
        {
            mActive = true;
            mVisible = true;
            mClosed = false;

            mContext->_createInternalResources(mEglDisplay, mEglConfig, mEglSurface, NULL);
            mContext->setCurrent();

            windowMovedOrResized();
            static_cast<GLES2RenderSystem*>(Ogre::Root::getSingletonPtr()->getRenderSystem())->resetRenderer(this);
        }
    }
}<commit_msg>fixed passing mMSAA into EGL_COVERAGE_SAMPLES_NV<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2013 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreRoot.h"
#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreStringConverter.h"
#include "OgreWindowEventUtilities.h"

#include "OgreGLES2Prerequisites.h"
#include "OgreGLES2RenderSystem.h"

#include "OgreAndroidEGLSupport.h"
#include "OgreAndroidEGLWindow.h"
#include "OgreAndroidEGLContext.h"
#include "OgreAndroidResourceManager.h"

#include <iostream>
#include <algorithm>
#include <climits>

namespace Ogre {
	AndroidEGLWindow::AndroidEGLWindow(AndroidEGLSupport *glsupport)
		: EGLWindow(glsupport),
		  mMaxBufferSize(32),
		  mMinBufferSize(16),
		  mMaxDepthSize(16),
		  mMaxStencilSize(0),
		  mMSAA(0),
		  mCSAA(0)
	{
	}

	AndroidEGLWindow::~AndroidEGLWindow()
	{
	}

	EGLContext* AndroidEGLWindow::createEGLContext() const
	{
		return new AndroidEGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface);
	}

	void AndroidEGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height )
	{
		// We don't have a native window.... but I think all android windows are origined
		left = top = 0;
	}

	void AndroidEGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams)
	{
	}

	void AndroidEGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title )
	{
	}

	void AndroidEGLWindow::reposition( int left, int top )
	{
	}

	void AndroidEGLWindow::resize(uint width, uint height)
	{
	}

	void AndroidEGLWindow::windowMovedOrResized()
	{
        if(mActive)
        {
            eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, (EGLint*)&mWidth);
            eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, (EGLint*)&mHeight);

            // Notify viewports of resize
            ViewportList::iterator it = mViewportList.begin();
            while( it != mViewportList.end() )
                (*it++).second->_updateDimensions();
        }
	}

    void AndroidEGLWindow::switchFullScreen(bool fullscreen)
    {

    }

    void AndroidEGLWindow::create(const String& name, uint width, uint height,
                               bool fullScreen, const NameValuePairList *miscParams)
    {
		mName = name;
        mWidth = width;
        mHeight = height;
        mLeft = 0;
        mTop = 0;
        mIsFullScreen = fullScreen;
        void* eglContext = NULL;
        AConfiguration* config = NULL;

        if (miscParams)
        {
            NameValuePairList::const_iterator opt;
            NameValuePairList::const_iterator end = miscParams->end();

            if ((opt = miscParams->find("currentGLContext")) != end &&
                StringConverter::parseBool(opt->second))
            {
                eglContext = eglGetCurrentContext();
                if (eglContext)
                {
                    OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                                "currentGLContext was specified with no current GL context",
                                "EGLWindow::create");
                }

                eglContext = eglGetCurrentContext();
                mEglSurface = eglGetCurrentSurface(EGL_DRAW);
            }

            if((opt = miscParams->find("externalWindowHandle")) != end)
            {
                mWindow = (ANativeWindow*)(Ogre::StringConverter::parseInt(opt->second));
            }

            if((opt = miscParams->find("androidConfig")) != end)
            {
                config = (AConfiguration*)(Ogre::StringConverter::parseInt(opt->second));
            }

            int ctxHandle = -1;
            if((miscParams->find("externalGLContext")) != end)
            {
                mIsExternalGLControl = true;
                ctxHandle = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("maxColourBufferSize")) != end)
            {
                mMaxBufferSize = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("maxDepthBufferSize")) != end)
            {
                mMaxDepthSize = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("maxStencilBufferSize")) != end)
            {
                mMaxStencilSize = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("minColourBufferSize")) != end)
            {
                mMinBufferSize = Ogre::StringConverter::parseInt(opt->second);
                if (mMinBufferSize > mMaxBufferSize) mMinBufferSize = mMaxBufferSize;
            }

			if((opt = miscParams->find("MSAA")) != end)
            {
                mMSAA = Ogre::StringConverter::parseInt(opt->second);
            }

			if((opt = miscParams->find("CSAA")) != end)
            {
                mCSAA = Ogre::StringConverter::parseInt(opt->second);
            }
        }

        initNativeCreatedWindow(miscParams);

        if (mEglSurface)
        {
            mEglConfig = mGLSupport->getGLConfigFromDrawable (mEglSurface, &width, &height);
        }

        if (!mEglConfig && eglContext)
        {
            mEglConfig = mGLSupport->getGLConfigFromContext(eglContext);

            if (!mEglConfig)
            {
                // This should never happen.
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                            "Unexpected failure to determine a EGLFBConfig",
                            "EGLWindow::create");
            }
        }

        mIsExternal = (mEglSurface != 0);

        if (!mEglConfig)
        {
			_createInternalResources(mWindow, config);
            mHwGamma = false;
        }

        mContext = createEGLContext();
        mContext->setCurrent();

        eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, (EGLint*)&mWidth);
        eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, (EGLint*)&mHeight);
        EGL_CHECK_ERROR

		mActive = true;
		mVisible = true;
		mClosed = false;
	}

    void AndroidEGLWindow::_destroyInternalResources()
    {
        GLES2RenderSystem::getResourceManager()->notifyOnContextLost();
        mContext->_destroyInternalResources();

        eglDestroySurface(mEglDisplay, mEglSurface);
        EGL_CHECK_ERROR

        eglTerminate(mEglDisplay);
        EGL_CHECK_ERROR

        mEglDisplay = 0;
        mEglSurface = 0;

        mActive = false;
		mVisible = false;
        mClosed = true;
    }

    void AndroidEGLWindow::_createInternalResources(NativeWindowType window, AConfiguration* config)
    {
        mWindow = window;

        int minAttribs[] = {
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
            EGL_BUFFER_SIZE, mMinBufferSize,
            EGL_DEPTH_SIZE, 16,
            EGL_NONE
        };

        int maxAttribs[] = {
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
			EGL_BUFFER_SIZE, mMaxBufferSize,
            EGL_DEPTH_SIZE, mMaxDepthSize,
            EGL_STENCIL_SIZE, mMaxStencilSize,
            EGL_NONE
        };

		bool bAASuccess = false;
		if (mCSAA)
		{
			try
			{
				int CSAAminAttribs[] = {
					EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
					EGL_BUFFER_SIZE, mMinBufferSize,
					EGL_DEPTH_SIZE, 16,
					EGL_COVERAGE_BUFFERS_NV, 1,
					EGL_COVERAGE_SAMPLES_NV, mCSAA,
					EGL_NONE
				};
				int CSAAmaxAttribs[] = {
					EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
					EGL_BUFFER_SIZE, mMaxBufferSize,
					EGL_DEPTH_SIZE, mMaxDepthSize,
					EGL_STENCIL_SIZE, mMaxStencilSize,
					EGL_COVERAGE_BUFFERS_NV, 1,
					EGL_COVERAGE_SAMPLES_NV, mCSAA,
					EGL_NONE
				};
				mEglConfig = mGLSupport->selectGLConfig(CSAAminAttribs, CSAAmaxAttribs);
				bAASuccess = true;
			}
			catch (Exception& e)
			{
				LogManager::getSingleton().logMessage("AndroidEGLWindow::_createInternalResources: setting CSAA failed");
			}
		}

		if (mMSAA && !bAASuccess)
		{
			try
			{
				int MSAAminAttribs[] = {
					EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
					EGL_BUFFER_SIZE, mMinBufferSize,
					EGL_DEPTH_SIZE, 16,
					EGL_SAMPLE_BUFFERS, 1,
					EGL_SAMPLES, mMSAA,
					EGL_NONE
				};
				int MSAAmaxAttribs[] = {
					EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
					EGL_BUFFER_SIZE, mMaxBufferSize,
					EGL_DEPTH_SIZE, mMaxDepthSize,
					EGL_STENCIL_SIZE, mMaxStencilSize,
					EGL_SAMPLE_BUFFERS, 1,
					EGL_SAMPLES, mMSAA,
					EGL_NONE
				};
				mEglConfig = mGLSupport->selectGLConfig(MSAAminAttribs, MSAAmaxAttribs);
				bAASuccess = true;
			}
			catch (Exception& e)
			{
				LogManager::getSingleton().logMessage("AndroidEGLWindow::_createInternalResources: setting MSAA failed");
			}
		}

        mEglDisplay = mGLSupport->getGLDisplay();
        if (!bAASuccess) mEglConfig = mGLSupport->selectGLConfig(minAttribs, maxAttribs);

        EGLint format;
        eglGetConfigAttrib(mEglDisplay, mEglConfig, EGL_NATIVE_VISUAL_ID, &format);
        EGL_CHECK_ERROR

        ANativeWindow_setBuffersGeometry(mWindow, 0, 0, format);

        mEglSurface = createSurfaceFromWindow(mEglDisplay, mWindow);

        if(config)
        {
            bool isLandscape = (int)AConfiguration_getOrientation(config) == 2;
            mGLSupport->setConfigOption("Orientation", isLandscape ? "Landscape" : "Portrait");
        }

        if(mContext)
        {
            mActive = true;
            mVisible = true;
            mClosed = false;

            mContext->_createInternalResources(mEglDisplay, mEglConfig, mEglSurface, NULL);
            mContext->setCurrent();

            windowMovedOrResized();
            static_cast<GLES2RenderSystem*>(Ogre::Root::getSingletonPtr()->getRenderSystem())->resetRenderer(this);
        }
    }
}<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreGLSLESLinkProgram.h"
#include "OgreGLSLESExtSupport.h"
#include "OgreGLSLESGpuProgram.h"
#include "OgreGLSLESProgram.h"
#include "OgreGLSLESLinkProgramManager.h"
#include "OgreStringVector.h"
#include "OgreLogManager.h"
#include "OgreGpuProgramManager.h"
#include "OgreStringConverter.h"

namespace Ogre {

	//-----------------------------------------------------------------------
	GLSLESLinkProgram::GLSLESLinkProgram(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram)
        : mVertexProgram(vertexProgram)
		, mFragmentProgram(fragmentProgram)
		, mUniformRefsBuilt(false)
        , mLinked(false)
		, mTriedToLinkAndFailed(false)
	{
		// init CustomAttributesIndexs
		for(size_t i = 0 ; i < VES_COUNT; i++)
			for(size_t j = 0 ; j < OGRE_MAX_TEXTURE_COORD_SETS; j++)
		{
			mCustomAttributesIndexes[i][j] = NULL_CUSTOM_ATTRIBUTES_INDEX;
		}

        if (!mVertexProgram && !mFragmentProgram)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Attempted to create a shader program without both a vertex and fragment program.",
                        "GLSLESLinkProgram::GLSLESLinkProgram");
        }
	}

	//-----------------------------------------------------------------------
	GLSLESLinkProgram::~GLSLESLinkProgram(void)
	{
		glDeleteProgram(mGLHandle);
        GL_CHECK_ERROR;
	}

	//-----------------------------------------------------------------------
	Ogre::String GLSLESLinkProgram::getCombinedName()
	{
		String name;
		if (mVertexProgram)
		{
			name += "Vertex Program:" ;
			name += mVertexProgram->getName();
		}
		if (mFragmentProgram)
		{
			name += " Fragment Program:" ;
			name += mFragmentProgram->getName();
		}
		return name;
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::activate(void)
	{
		if (!mLinked && !mTriedToLinkAndFailed)
		{
			glGetError(); // Clean up the error. Otherwise will flood log.
			mGLHandle = glCreateProgram();
			GL_CHECK_ERROR

			if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() &&
				GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) )
			{
				getMicrocodeFromCache();
			}
			else
			{
				compileAndLink();
			}

			buildGLUniformReferences();
		}

		if (mLinked)
		{
            GL_CHECK_ERROR
            glUseProgram( mGLHandle );
            GL_CHECK_ERROR
		}
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::getMicrocodeFromCache(void)
	{
		GpuProgramManager::Microcode cacheMicrocode =
			GpuProgramManager::getSingleton().getMicrocodeFromCache(getCombinedName());

		// add to the microcode to the cache
		String name;
		name = getCombinedName();

		// turns out we need this param when loading
		GLenum binaryFormat = 0;

		cacheMicrocode->seek(0);

		// get size of binary
		cacheMicrocode->read(&binaryFormat, sizeof(GLenum));

#if GL_OES_get_program_binary
		// load binary
		glProgramBinaryOES( mGLHandle,
							binaryFormat,
							cacheMicrocode->getPtr(),
							binaryLength
			);
#endif
		GLint   success = 0;
		glGetProgramiv(mGLHandle, GL_LINK_STATUS, &success);
		if (!success)
		{
			//
			// Something must have changed since the program binaries
			// were cached away.  Fallback to source shader loading path,
			// and then retrieve and cache new program binaries once again.
			//
			compileAndLink();
		}

	}

	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::compileAndLink()
	{
		// compile and attach Vertex Program
		if (!mVertexProgram->getGLSLProgram()->compile(true))
		{
			// todo error
			return;
		}
        mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
        setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded());

		// compile and attach Fragment Program
		if (!mFragmentProgram->getGLSLProgram()->compile(true))
		{
			// todo error
			return;
		}
        mFragmentProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);

		// the link
		glLinkProgram( mGLHandle );
		GL_CHECK_ERROR
			glGetProgramiv( mGLHandle, GL_LINK_STATUS, &mLinked );
		GL_CHECK_ERROR

		mTriedToLinkAndFailed = !mLinked;

		logObjectInfo( getCombinedName() + String("GLSL link result : "), mGLHandle );
		if(mLinked)
		{
			if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() )
			{
				// add to the microcode to the cache
				String name;
				name = getCombinedName();

				// get buffer size
				GLint binaryLength = 0;
#if GL_OES_get_program_binary
				glGetProgramiv(mGLHandle, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength);
#endif

                // create microcode
                GpuProgramManager::Microcode newMicrocode =
                    GpuProgramManager::getSingleton().createMicrocode(binaryLength + sizeof(GLenum));

#if GL_OES_get_program_binary
				// get binary
				glGetProgramBinaryOES(mGLHandle, binaryLength, NULL, (GLenum *)newMicrocode->getPtr(), newMicrocode->getPtr() + sizeof(GLenum));
#endif

        		// add to the microcode to the cache
				GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode);
			}
		}
	}
	//-----------------------------------------------------------------------
	const char * getAttributeSemanticString(VertexElementSemantic semantic)
	{
		switch(semantic)
		{
			case VES_POSITION:
				return "vertex";
			case VES_BLEND_WEIGHTS:
				return "blendWeights";
			case VES_NORMAL:
				return "normal";
			case VES_DIFFUSE:
				return "colour";
			case VES_SPECULAR:
				return "secondary_colour";
			case VES_BLEND_INDICES:
				return "blendIndices";
			case VES_TANGENT:
				return "tangent";
			case VES_BINORMAL:
				return "binormal";
			case VES_TEXTURE_COORDINATES:
				return "uv";
			default:
				assert(false && "Missing attribute!");
				return 0;
		};

	}
	//-----------------------------------------------------------------------
	GLuint GLSLESLinkProgram::getAttributeIndex(VertexElementSemantic semantic, uint index)
	{
		GLint res = mCustomAttributesIndexes[semantic-1][index];
		if (res == NULL_CUSTOM_ATTRIBUTES_INDEX)
		{
			const char * attString = getAttributeSemanticString(semantic);
			GLint attrib = glGetAttribLocation(mGLHandle, attString);

			// sadly position is a special case
			if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION)
			{
				attrib = glGetAttribLocation(mGLHandle, "position");
			}

			// for uv and other case the index is a part of the name
			if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX)
			{
				String attStringWithSemantic = String(attString) + StringConverter::toString(index);
				attrib = glGetAttribLocation(mGLHandle, attStringWithSemantic.c_str());
			}

			// update mCustomAttributesIndexes with the index we found (or didn't find)
			mCustomAttributesIndexes[semantic-1][index] = attrib;
			res = attrib;
		}
		return (GLuint)res;
	}
	//-----------------------------------------------------------------------
	bool GLSLESLinkProgram::isAttributeValid(VertexElementSemantic semantic, uint index)
	{
		return (GLint)(getAttributeIndex(semantic, index)) != NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX;
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::buildGLUniformReferences(void)
	{
		if (!mUniformRefsBuilt)
		{
			const GpuConstantDefinitionMap* vertParams = 0;
			const GpuConstantDefinitionMap* fragParams = 0;
			if (mVertexProgram)
			{
				vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map);
			}
			if (mFragmentProgram)
			{
				fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map);
			}

			GLSLESLinkProgramManager::getSingleton().extractUniforms(
				mGLHandle, vertParams, fragParams, mGLUniformReferences);

			mUniformRefsBuilt = true;
		}
	}

	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params,
		uint16 mask, GpuProgramType fromProgType)
	{
		// Iterate through uniform reference list and update uniform values
		GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
		GLUniformReferenceIterator endUniform = mGLUniformReferences.end();

		for (;currentUniform != endUniform; ++currentUniform)
		{
			// Only pull values from buffer it's supposed to be in (vertex or fragment)
			// This method will be called twice, once for vertex program params,
			// and once for fragment program params.
			if (fromProgType == currentUniform->mSourceProgType)
			{
				const GpuConstantDefinition* def = currentUniform->mConstantDef;
				if (def->variability & mask)
				{
					GLsizei glArraySize = (GLsizei)def->arraySize;

					// Get the index in the parameter real list
					switch (def->constType)
					{
					case GCT_FLOAT1:
						glUniform1fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT2:
						glUniform2fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT3:
						glUniform3fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT4:
						glUniform4fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_2X2:
						glUniformMatrix2fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_3X3:
						glUniformMatrix3fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_4X4:
						glUniformMatrix4fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_INT1:
						glUniform1iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT2:
						glUniform2iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT3:
						glUniform3iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT4:
						glUniform4iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_SAMPLER1D:
					case GCT_SAMPLER1DSHADOW:
					case GCT_SAMPLER2D:
					case GCT_SAMPLER2DSHADOW:
					case GCT_SAMPLER3D:
					case GCT_SAMPLERCUBE:
						// Samplers handled like 1-element ints
						glUniform1iv(currentUniform->mLocation, 1,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_2X3:
					case GCT_MATRIX_2X4:
					case GCT_MATRIX_3X2:
					case GCT_MATRIX_3X4:
					case GCT_MATRIX_4X2:
					case GCT_MATRIX_4X3:
                    case GCT_UNKNOWN:
                        break;

					} // End switch
                    GL_CHECK_ERROR;
				} // Variability & mask
			} // fromProgType == currentUniform->mSourceProgType

  		} // End for
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params)
	{
		if (params->hasPassIterationNumber())
		{
			size_t index = params->getPassIterationNumberIndex();

			GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
			GLUniformReferenceIterator endUniform = mGLUniformReferences.end();

			// Need to find the uniform that matches the multi pass entry
			for (;currentUniform != endUniform; ++currentUniform)
			{
				// Get the index in the parameter real list
				if (index == currentUniform->mConstantDef->physicalIndex)
				{
					glUniform1fv(currentUniform->mLocation, 1, params->getFloatPointer(index));
                    GL_CHECK_ERROR;
					// There will only be one multipass entry
					return;
				}
			}
		}
    }
} // namespace Ogre
<commit_msg>GLES2 render system: Added a var init that was missing (binaryLength in GLSLESLinkProgram::getMicrocodeFromCache).<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreGLSLESLinkProgram.h"
#include "OgreGLSLESExtSupport.h"
#include "OgreGLSLESGpuProgram.h"
#include "OgreGLSLESProgram.h"
#include "OgreGLSLESLinkProgramManager.h"
#include "OgreStringVector.h"
#include "OgreLogManager.h"
#include "OgreGpuProgramManager.h"
#include "OgreStringConverter.h"

namespace Ogre {

	//-----------------------------------------------------------------------
	GLSLESLinkProgram::GLSLESLinkProgram(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram)
        : mVertexProgram(vertexProgram)
		, mFragmentProgram(fragmentProgram)
		, mUniformRefsBuilt(false)
        , mLinked(false)
		, mTriedToLinkAndFailed(false)
	{
		// init CustomAttributesIndexs
		for(size_t i = 0 ; i < VES_COUNT; i++)
			for(size_t j = 0 ; j < OGRE_MAX_TEXTURE_COORD_SETS; j++)
		{
			mCustomAttributesIndexes[i][j] = NULL_CUSTOM_ATTRIBUTES_INDEX;
		}

        if (!mVertexProgram && !mFragmentProgram)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Attempted to create a shader program without both a vertex and fragment program.",
                        "GLSLESLinkProgram::GLSLESLinkProgram");
        }
	}

	//-----------------------------------------------------------------------
	GLSLESLinkProgram::~GLSLESLinkProgram(void)
	{
		glDeleteProgram(mGLHandle);
        GL_CHECK_ERROR;
	}

	//-----------------------------------------------------------------------
	Ogre::String GLSLESLinkProgram::getCombinedName()
	{
		String name;
		if (mVertexProgram)
		{
			name += "Vertex Program:" ;
			name += mVertexProgram->getName();
		}
		if (mFragmentProgram)
		{
			name += " Fragment Program:" ;
			name += mFragmentProgram->getName();
		}
		return name;
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::activate(void)
	{
		if (!mLinked && !mTriedToLinkAndFailed)
		{
			glGetError(); // Clean up the error. Otherwise will flood log.
			mGLHandle = glCreateProgram();
			GL_CHECK_ERROR

			if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() &&
				GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) )
			{
				getMicrocodeFromCache();
			}
			else
			{
				compileAndLink();
			}

			buildGLUniformReferences();
		}

		if (mLinked)
		{
            GL_CHECK_ERROR
            glUseProgram( mGLHandle );
            GL_CHECK_ERROR
		}
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::getMicrocodeFromCache(void)
	{
		GpuProgramManager::Microcode cacheMicrocode =
			GpuProgramManager::getSingleton().getMicrocodeFromCache(getCombinedName());

		// add to the microcode to the cache
		String name;
		name = getCombinedName();

		// turns out we need this param when loading
		GLenum binaryFormat = 0;

		cacheMicrocode->seek(0);

		// get size of binary
		cacheMicrocode->read(&binaryFormat, sizeof(GLenum));

        GLint binaryLength = cacheMicrocode->size() - sizeof(GLenum);

#if GL_OES_get_program_binary
		// load binary
		glProgramBinaryOES( mGLHandle,
							binaryFormat,
							cacheMicrocode->getPtr(),
							binaryLength
			);
#endif
		GLint   success = 0;
		glGetProgramiv(mGLHandle, GL_LINK_STATUS, &success);
		if (!success)
		{
			//
			// Something must have changed since the program binaries
			// were cached away.  Fallback to source shader loading path,
			// and then retrieve and cache new program binaries once again.
			//
			compileAndLink();
		}

	}

	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::compileAndLink()
	{
		// compile and attach Vertex Program
		if (!mVertexProgram->getGLSLProgram()->compile(true))
		{
			// todo error
			return;
		}
        mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
        setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded());

		// compile and attach Fragment Program
		if (!mFragmentProgram->getGLSLProgram()->compile(true))
		{
			// todo error
			return;
		}
        mFragmentProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);

		// the link
		glLinkProgram( mGLHandle );
		GL_CHECK_ERROR
			glGetProgramiv( mGLHandle, GL_LINK_STATUS, &mLinked );
		GL_CHECK_ERROR

		mTriedToLinkAndFailed = !mLinked;

		logObjectInfo( getCombinedName() + String("GLSL link result : "), mGLHandle );
		if(mLinked)
		{
			if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() )
			{
				// add to the microcode to the cache
				String name;
				name = getCombinedName();

				// get buffer size
				GLint binaryLength = 0;
#if GL_OES_get_program_binary
				glGetProgramiv(mGLHandle, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength);
#endif

                // create microcode
                GpuProgramManager::Microcode newMicrocode =
                    GpuProgramManager::getSingleton().createMicrocode(binaryLength + sizeof(GLenum));

#if GL_OES_get_program_binary
				// get binary
				glGetProgramBinaryOES(mGLHandle, binaryLength, NULL, (GLenum *)newMicrocode->getPtr(), newMicrocode->getPtr() + sizeof(GLenum));
#endif

        		// add to the microcode to the cache
				GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode);
			}
		}
	}
	//-----------------------------------------------------------------------
	const char * getAttributeSemanticString(VertexElementSemantic semantic)
	{
		switch(semantic)
		{
			case VES_POSITION:
				return "vertex";
			case VES_BLEND_WEIGHTS:
				return "blendWeights";
			case VES_NORMAL:
				return "normal";
			case VES_DIFFUSE:
				return "colour";
			case VES_SPECULAR:
				return "secondary_colour";
			case VES_BLEND_INDICES:
				return "blendIndices";
			case VES_TANGENT:
				return "tangent";
			case VES_BINORMAL:
				return "binormal";
			case VES_TEXTURE_COORDINATES:
				return "uv";
			default:
				assert(false && "Missing attribute!");
				return 0;
		};

	}
	//-----------------------------------------------------------------------
	GLuint GLSLESLinkProgram::getAttributeIndex(VertexElementSemantic semantic, uint index)
	{
		GLint res = mCustomAttributesIndexes[semantic-1][index];
		if (res == NULL_CUSTOM_ATTRIBUTES_INDEX)
		{
			const char * attString = getAttributeSemanticString(semantic);
			GLint attrib = glGetAttribLocation(mGLHandle, attString);

			// sadly position is a special case
			if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION)
			{
				attrib = glGetAttribLocation(mGLHandle, "position");
			}

			// for uv and other case the index is a part of the name
			if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX)
			{
				String attStringWithSemantic = String(attString) + StringConverter::toString(index);
				attrib = glGetAttribLocation(mGLHandle, attStringWithSemantic.c_str());
			}

			// update mCustomAttributesIndexes with the index we found (or didn't find)
			mCustomAttributesIndexes[semantic-1][index] = attrib;
			res = attrib;
		}
		return (GLuint)res;
	}
	//-----------------------------------------------------------------------
	bool GLSLESLinkProgram::isAttributeValid(VertexElementSemantic semantic, uint index)
	{
		return (GLint)(getAttributeIndex(semantic, index)) != NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX;
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::buildGLUniformReferences(void)
	{
		if (!mUniformRefsBuilt)
		{
			const GpuConstantDefinitionMap* vertParams = 0;
			const GpuConstantDefinitionMap* fragParams = 0;
			if (mVertexProgram)
			{
				vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map);
			}
			if (mFragmentProgram)
			{
				fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map);
			}

			GLSLESLinkProgramManager::getSingleton().extractUniforms(
				mGLHandle, vertParams, fragParams, mGLUniformReferences);

			mUniformRefsBuilt = true;
		}
	}

	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params,
		uint16 mask, GpuProgramType fromProgType)
	{
		// Iterate through uniform reference list and update uniform values
		GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
		GLUniformReferenceIterator endUniform = mGLUniformReferences.end();

		for (;currentUniform != endUniform; ++currentUniform)
		{
			// Only pull values from buffer it's supposed to be in (vertex or fragment)
			// This method will be called twice, once for vertex program params,
			// and once for fragment program params.
			if (fromProgType == currentUniform->mSourceProgType)
			{
				const GpuConstantDefinition* def = currentUniform->mConstantDef;
				if (def->variability & mask)
				{
					GLsizei glArraySize = (GLsizei)def->arraySize;

					// Get the index in the parameter real list
					switch (def->constType)
					{
					case GCT_FLOAT1:
						glUniform1fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT2:
						glUniform2fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT3:
						glUniform3fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT4:
						glUniform4fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_2X2:
						glUniformMatrix2fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_3X3:
						glUniformMatrix3fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_4X4:
						glUniformMatrix4fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_INT1:
						glUniform1iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT2:
						glUniform2iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT3:
						glUniform3iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT4:
						glUniform4iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_SAMPLER1D:
					case GCT_SAMPLER1DSHADOW:
					case GCT_SAMPLER2D:
					case GCT_SAMPLER2DSHADOW:
					case GCT_SAMPLER3D:
					case GCT_SAMPLERCUBE:
						// Samplers handled like 1-element ints
						glUniform1iv(currentUniform->mLocation, 1,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_2X3:
					case GCT_MATRIX_2X4:
					case GCT_MATRIX_3X2:
					case GCT_MATRIX_3X4:
					case GCT_MATRIX_4X2:
					case GCT_MATRIX_4X3:
                    case GCT_UNKNOWN:
                        break;

					} // End switch
                    GL_CHECK_ERROR;
				} // Variability & mask
			} // fromProgType == currentUniform->mSourceProgType

  		} // End for
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params)
	{
		if (params->hasPassIterationNumber())
		{
			size_t index = params->getPassIterationNumberIndex();

			GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
			GLUniformReferenceIterator endUniform = mGLUniformReferences.end();

			// Need to find the uniform that matches the multi pass entry
			for (;currentUniform != endUniform; ++currentUniform)
			{
				// Get the index in the parameter real list
				if (index == currentUniform->mConstantDef->physicalIndex)
				{
					glUniform1fv(currentUniform->mLocation, 1, params->getFloatPointer(index));
                    GL_CHECK_ERROR;
					// There will only be one multipass entry
					return;
				}
			}
		}
    }
} // namespace Ogre
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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 "stopwatch.hxx"
#include "pool.hxx"
#include "net/SocketDescriptor.hxx"
#include "net/StaticSocketAddress.hxx"
#include "net/ToString.hxx"
#include "util/StaticArray.hxx"
#include "util/WritableBuffer.hxx"

#include <daemon/log.h>

#include <chrono>

#include <time.h>
#include <assert.h>
#include <string.h>
#include <sys/resource.h>

enum {
    STOPWATCH_VERBOSE = 3,
};

struct StopwatchEvent {
    const char *name;

    std::chrono::steady_clock::time_point time;

    void Init(const char *_name) {
        name = _name;
        time = std::chrono::steady_clock::now();
    }
};

struct Stopwatch {
    struct pool *pool;

#ifndef NDEBUG
    struct pool_notify_state pool_notify;
#endif

    const char *const name;

    StaticArray<StopwatchEvent, 16> events;

    /**
     * Our own resource usage, measured when the stopwatch was
     * started.
     */
    struct rusage self;

    Stopwatch(struct pool &_pool, const char *_name)
        :pool(&_pool), name(_name) {
        ::pool_notify(pool, &pool_notify);

        events.append().Init(name);

        getrusage(RUSAGE_SELF, &self);
    }
};

static bool stopwatch_enabled;

void
stopwatch_enable()
{
    assert(!stopwatch_enabled);

    stopwatch_enabled = true;
}

bool
stopwatch_is_enabled()
{
    return stopwatch_enabled && daemon_log_config.verbose >= STOPWATCH_VERBOSE;
}

Stopwatch *
stopwatch_new(struct pool *pool, const char *name, const char *suffix)
{
    if (!stopwatch_enabled || daemon_log_config.verbose < STOPWATCH_VERBOSE)
        return nullptr;

    if (suffix == nullptr)
        name = p_strdup(pool, name);
    else
        name = p_strcat(pool, name, suffix, nullptr);

    constexpr size_t MAX_NAME = 96;
    if (strlen(name) > MAX_NAME)
        name = p_strndup(pool, name, MAX_NAME);

    return NewFromPool<Stopwatch>(*pool, *pool, name);
}

Stopwatch *
stopwatch_new(struct pool *pool, SocketAddress address, const char *suffix)
{
    char buffer[1024];

    if (!stopwatch_enabled || daemon_log_config.verbose < STOPWATCH_VERBOSE)
        return nullptr;

    const char *name = ToString(buffer, sizeof(buffer), address)
        ? buffer
        : "unknown";

    return stopwatch_new(pool, name, suffix);
}

Stopwatch *
stopwatch_new(struct pool *pool, SocketDescriptor fd, const char *suffix)
{
    if (!stopwatch_enabled || daemon_log_config.verbose < STOPWATCH_VERBOSE)
        return nullptr;

    const auto address = fd.GetPeerAddress();
    return address.IsDefined()
        ? stopwatch_new(pool, address, suffix)
        : stopwatch_new(pool, "unknown", suffix);
}

void
stopwatch_event(Stopwatch *stopwatch, const char *name)
{
    if (!stopwatch_enabled || daemon_log_config.verbose < STOPWATCH_VERBOSE)
        return;

    assert(stopwatch != nullptr);
    assert(name != nullptr);

    if (stopwatch->events.full())
        /* array is full, do not record any more events */
        return;

    stopwatch->events.append().Init(name);
}

static constexpr long
ToLongMs(std::chrono::steady_clock::duration d)
{
    return std::chrono::duration_cast<std::chrono::milliseconds>(d).count();
}

static long
timeval_diff_ms(const struct timeval *a, const struct timeval *b)
{
    return (a->tv_sec - b->tv_sec) * 1000 +
        (a->tv_usec - b->tv_usec) / 1000;
}

template<typename... Args>
static void
AppendFormat(WritableBuffer<char> &buffer, const char *fmt, Args&&... args)
{
    int r = snprintf(buffer.data, buffer.size, fmt, args...);
    if (r > 0)
        buffer.skip_front(std::min(size_t(r), buffer.size - 1));
}

void
stopwatch_dump(const Stopwatch *stopwatch)
{
    struct rusage self;

    if (!stopwatch_enabled || daemon_log_config.verbose < STOPWATCH_VERBOSE)
        return;

    assert(stopwatch != nullptr);
    assert(!stopwatch->events.empty());

    if (stopwatch->events.size() < 2)
        /* nothing was recorded (except for the initial event) */
        return;

    char message[1024];

    WritableBuffer<char> b(message, sizeof(message));
    AppendFormat(b, "stopwatch[%s]:", stopwatch->name);

    for (const auto &i : stopwatch->events)
        AppendFormat(b, " %s=%ldms",
                     i.name,
                     ToLongMs(i.time - stopwatch->events.front().time));

    getrusage(RUSAGE_SELF, &self);
    AppendFormat(b, " (beng-proxy=%ld+%ldms)",
                 timeval_diff_ms(&self.ru_utime,
                                 &stopwatch->self.ru_utime),
                 timeval_diff_ms(&self.ru_stime,
                                 &stopwatch->self.ru_stime));

    daemon_log(STOPWATCH_VERBOSE, "%s\n", message);
}
<commit_msg>stopwatch: use stopwatch_is_enabled() internally<commit_after>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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 "stopwatch.hxx"
#include "pool.hxx"
#include "net/SocketDescriptor.hxx"
#include "net/StaticSocketAddress.hxx"
#include "net/ToString.hxx"
#include "util/StaticArray.hxx"
#include "util/WritableBuffer.hxx"

#include <daemon/log.h>

#include <chrono>

#include <time.h>
#include <assert.h>
#include <string.h>
#include <sys/resource.h>

enum {
    STOPWATCH_VERBOSE = 3,
};

struct StopwatchEvent {
    const char *name;

    std::chrono::steady_clock::time_point time;

    void Init(const char *_name) {
        name = _name;
        time = std::chrono::steady_clock::now();
    }
};

struct Stopwatch {
    struct pool *pool;

#ifndef NDEBUG
    struct pool_notify_state pool_notify;
#endif

    const char *const name;

    StaticArray<StopwatchEvent, 16> events;

    /**
     * Our own resource usage, measured when the stopwatch was
     * started.
     */
    struct rusage self;

    Stopwatch(struct pool &_pool, const char *_name)
        :pool(&_pool), name(_name) {
        ::pool_notify(pool, &pool_notify);

        events.append().Init(name);

        getrusage(RUSAGE_SELF, &self);
    }
};

static bool stopwatch_enabled;

void
stopwatch_enable()
{
    assert(!stopwatch_enabled);

    stopwatch_enabled = true;
}

bool
stopwatch_is_enabled()
{
    return stopwatch_enabled && daemon_log_config.verbose >= STOPWATCH_VERBOSE;
}

Stopwatch *
stopwatch_new(struct pool *pool, const char *name, const char *suffix)
{
    if (!stopwatch_is_enabled())
        return nullptr;

    if (suffix == nullptr)
        name = p_strdup(pool, name);
    else
        name = p_strcat(pool, name, suffix, nullptr);

    constexpr size_t MAX_NAME = 96;
    if (strlen(name) > MAX_NAME)
        name = p_strndup(pool, name, MAX_NAME);

    return NewFromPool<Stopwatch>(*pool, *pool, name);
}

Stopwatch *
stopwatch_new(struct pool *pool, SocketAddress address, const char *suffix)
{
    char buffer[1024];

    if (!stopwatch_is_enabled())
        return nullptr;

    const char *name = ToString(buffer, sizeof(buffer), address)
        ? buffer
        : "unknown";

    return stopwatch_new(pool, name, suffix);
}

Stopwatch *
stopwatch_new(struct pool *pool, SocketDescriptor fd, const char *suffix)
{
    if (!stopwatch_is_enabled())
        return nullptr;

    const auto address = fd.GetPeerAddress();
    return address.IsDefined()
        ? stopwatch_new(pool, address, suffix)
        : stopwatch_new(pool, "unknown", suffix);
}

void
stopwatch_event(Stopwatch *stopwatch, const char *name)
{
    if (!stopwatch_is_enabled())
        return;

    assert(stopwatch != nullptr);
    assert(name != nullptr);

    if (stopwatch->events.full())
        /* array is full, do not record any more events */
        return;

    stopwatch->events.append().Init(name);
}

static constexpr long
ToLongMs(std::chrono::steady_clock::duration d)
{
    return std::chrono::duration_cast<std::chrono::milliseconds>(d).count();
}

static long
timeval_diff_ms(const struct timeval *a, const struct timeval *b)
{
    return (a->tv_sec - b->tv_sec) * 1000 +
        (a->tv_usec - b->tv_usec) / 1000;
}

template<typename... Args>
static void
AppendFormat(WritableBuffer<char> &buffer, const char *fmt, Args&&... args)
{
    int r = snprintf(buffer.data, buffer.size, fmt, args...);
    if (r > 0)
        buffer.skip_front(std::min(size_t(r), buffer.size - 1));
}

void
stopwatch_dump(const Stopwatch *stopwatch)
{
    struct rusage self;

    if (!stopwatch_is_enabled())
        return;

    assert(stopwatch != nullptr);
    assert(!stopwatch->events.empty());

    if (stopwatch->events.size() < 2)
        /* nothing was recorded (except for the initial event) */
        return;

    char message[1024];

    WritableBuffer<char> b(message, sizeof(message));
    AppendFormat(b, "stopwatch[%s]:", stopwatch->name);

    for (const auto &i : stopwatch->events)
        AppendFormat(b, " %s=%ldms",
                     i.name,
                     ToLongMs(i.time - stopwatch->events.front().time));

    getrusage(RUSAGE_SELF, &self);
    AppendFormat(b, " (beng-proxy=%ld+%ldms)",
                 timeval_diff_ms(&self.ru_utime,
                                 &stopwatch->self.ru_utime),
                 timeval_diff_ms(&self.ru_stime,
                                 &stopwatch->self.ru_stime));

    daemon_log(STOPWATCH_VERBOSE, "%s\n", message);
}
<|endoftext|>