<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/lib/p10_pm_utils.H $      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2019,2021                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file  p10_pm_utils.H
/// @brief General utility functions
///
/// *HWP HWP Owner        : Greg Still <stillgs@us.ibm.com>
/// *HWP FW Owner         : Prasad BG Ranganath <prasadbgr@in.ibm.com>
/// *Team                 : PM
/// *Consumed by          : HB:CRO
///

#ifndef __PM_UTILS_H__
#define __PM_UTILS_H__

#include <p10_pm_get_poundv_bucket.H>

// Byte-reverse a 16-bit integer if on a little-endian machine
uint16_t revle16(const uint16_t i_x);

// Byte-reverse a 32-bit integer if on a little-endian machine
uint32_t revle32(const uint32_t i_x);

// Byte-reverse a 64-bit integer if on a little-endian machine
uint64_t revle64(const uint64_t i_x);

/// ----------------------------------------------------------------------------
/// @brief Compute bias value for pre-defined percentage unit
/// @param[in]     i_value Biased value
/// @return bias value
/// ----------------------------------------------------------------------------
double calc_bias(const int8_t i_value);

/// ----------------------------------------------------------------------------
/// @brief Compute smallest value for a given input
/// @param[in]     x value
/// @return smallest value
/// ----------------------------------------------------------------------------
double internal_ceil(double x);

/// ----------------------------------------------------------------------------
/// @brief Compute largest value for a given input
/// @param[in]     x value
/// @return largest value
/// ----------------------------------------------------------------------------
double internal_floor(double x);

/// -----------------------------------------------------------------------
/// @brief Compute the rounded value for a given input
/// @param[in]     x value
/// @return rounded value
/// -----------------------------------------------------------------------
double internal_round(double x);

/// ----------------------------------------------------------------------------
/// @brief Adjust bias value for given frequency value
/// @param[in]     i_value  frequency value
/// @param[in]     i_bias_0p5pct  bias value
/// @return computed biase value
/// ----------------------------------------------------------------------------
uint32_t bias_adjust_mhz(
    const uint32_t i_value,
    const int32_t i_bias_0p5pct);

/// ----------------------------------------------------------------------------
/// @brief Adjust bias value for given vdd/vcs voltage
/// @param[in]     i_value vdd/vcs value
/// @param[in]     i_bias_0p5pct  bias value
/// @return computed biase value
/// ----------------------------------------------------------------------------
uint32_t bias_adjust_mv(
    const uint32_t i_value,
    const int8_t i_bias_0p5pct);

/// ----------------------------------------------------------------------------
/// @brief Get the WOF Table Header
/// @param[in]    i_proc_target Chip Target
/// @param[out]   i_wof_table_data points to WOF data tables
/// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// ----------------------------------------------------------------------------
fapi2::ReturnCode wof_get_tables(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    fapi2::ATTR_WOF_TABLE_DATA_Type* i_wof_table_data);

/// ----------------------------------------------------------------------------
/// @brief Validate the WOF Table Header
/// @param[in]    i_proc_target Chip Target
/// @param[in]    i_wof_table_data points to WOF data tables
/// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// ----------------------------------------------------------------------------
fapi2::ReturnCode wof_validate_header(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    fapi2::ATTR_WOF_TABLE_DATA_Type* i_wof_table_data);

/// ----------------------------------------------------------------------------
/// @brief Apply the WOF Table Overrides to #V
/// @param[in]    i_proc_target Chip Target
/// @param[inout] o_wof_table_data points to WOF data tables
/// @param[in]    i_wof_state enabled or disabled
/// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// ----------------------------------------------------------------------------
fapi2::ReturnCode wof_apply_overrides(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    fapi2::voltageBucketData_t* o_poundV_data,
    const bool i_wof_state);

/// ----------------------------------------------------------------------------
/// @brief Print the raw #V bucket structure
/// @param[in]    o_poundV_data Pointer to structure
/// ----------------------------------------------------------------------------
fapi2::ReturnCode print_voltage_bucket(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    fapi2::voltageBucketData_t* o_poundV_data);

#endif  // __PM_UTILS_H__
<commit_msg>DFT Updates to support new ekb changes<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/lib/p10_pm_utils.H $      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2019,2021                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file  p10_pm_utils.H
/// @brief General utility functions
///
/// *HWP HWP Owner        : Greg Still <stillgs@us.ibm.com>
/// *HWP FW Owner         : Prasad BG Ranganath <prasadbgr@in.ibm.com>
/// *Team                 : PM
/// *Consumed by          : HB:CRO
///

#ifndef __PM_UTILS_H__
#define __PM_UTILS_H__

#include <p10_pm_get_poundv_bucket.H>

// Byte-reverse a 16-bit integer if on a little-endian machine
uint16_t revle16(const uint16_t i_x);

// Byte-reverse a 32-bit integer if on a little-endian machine
uint32_t revle32(const uint32_t i_x);

// Byte-reverse a 64-bit integer if on a little-endian machine
uint64_t revle64(const uint64_t i_x);

/// ----------------------------------------------------------------------------
/// @brief Compute bias value for pre-defined percentage unit
/// @param[in]     i_value Biased value
/// @return bias value
/// ----------------------------------------------------------------------------
double calc_bias(const int8_t i_value);

/// ----------------------------------------------------------------------------
/// @brief Compute smallest value for a given input
/// @param[in]     x value
/// @return smallest value
/// ----------------------------------------------------------------------------
double internal_ceil(double x);

/// ----------------------------------------------------------------------------
/// @brief Compute largest value for a given input
/// @param[in]     x value
/// @return largest value
/// ----------------------------------------------------------------------------
double internal_floor(double x);

/// -----------------------------------------------------------------------
/// @brief Compute the rounded value for a given input
/// @param[in]     x value
/// @return rounded value
/// -----------------------------------------------------------------------
double internal_round(double x);

/// ----------------------------------------------------------------------------
/// @brief Adjust bias value for given frequency value
/// @param[in]     i_value  frequency value
/// @param[in]     i_bias_0p5pct  bias value
/// @return computed biase value
/// ----------------------------------------------------------------------------
uint32_t bias_adjust_mhz(
    const uint32_t i_value,
    const int32_t i_bias_0p5pct);

/// ----------------------------------------------------------------------------
/// @brief Adjust bias value for given vdd/vcs voltage
/// @param[in]     i_value vdd/vcs value
/// @param[in]     i_bias_0p5pct  bias value
/// @return computed biase value
/// ----------------------------------------------------------------------------
uint32_t bias_adjust_mv(
    const uint32_t i_value,
    const int8_t i_bias_0p5pct);

#ifndef DFT
/// ----------------------------------------------------------------------------
/// @brief Get the WOF Table Header
/// @param[in]    i_proc_target Chip Target
/// @param[out]   i_wof_table_data points to WOF data tables
/// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// ----------------------------------------------------------------------------
fapi2::ReturnCode wof_get_tables(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    fapi2::ATTR_WOF_TABLE_DATA_Type* i_wof_table_data);

/// ----------------------------------------------------------------------------
/// @brief Validate the WOF Table Header
/// @param[in]    i_proc_target Chip Target
/// @param[in]    i_wof_table_data points to WOF data tables
/// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// ----------------------------------------------------------------------------
fapi2::ReturnCode wof_validate_header(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    fapi2::ATTR_WOF_TABLE_DATA_Type* i_wof_table_data);
#endif //DFT

/// ----------------------------------------------------------------------------
/// @brief Apply the WOF Table Overrides to #V
/// @param[in]    i_proc_target Chip Target
/// @param[inout] o_wof_table_data points to WOF data tables
/// @param[in]    i_wof_state enabled or disabled
/// @return fapi2::ReturnCode: FAPI2_RC_SUCCESS if success, else error code.
/// ----------------------------------------------------------------------------
fapi2::ReturnCode wof_apply_overrides(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    fapi2::voltageBucketData_t* o_poundV_data,
    const bool i_wof_state);

/// ----------------------------------------------------------------------------
/// @brief Print the raw #V bucket structure
/// @param[in]    o_poundV_data Pointer to structure
/// ----------------------------------------------------------------------------
fapi2::ReturnCode print_voltage_bucket(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    fapi2::voltageBucketData_t* o_poundV_data);

#endif  // __PM_UTILS_H__
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_perst_phb.H $      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_perst_phb.H
/// @brief Procedure to assert/deassert PERST from PHB. (FAPI2)
///
// *HWP HWP Owner: Ricardo Mata Jr. ricmata@us.ibm.com
// *HWP FW Owner: Thi Tran thi@us.ibm.com
// *HWP Team: Nest
// *HWP Level: 2
// *HWP Consumed by: HB

#ifndef _P9_PERST_PHB_H_
#define _P9_PERST_PHB_H_

//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------
#ifndef _PERST_ACTION_
#define _PERST_ACTION_

enum PERST_ACTION
{
    ACTIVATE_PERST,     //Drive PERST signal active from the PHB. Put in to Reset.
    DEACTIVATE_PERST        //Drive PERST signal inactive from the PHB. Take out of Reset.
};
#endif

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include <fapi2.H>
#include <p9_phb_hv_utils.H>

//-----------------------------------------------------------------------------------
// Structure definitions
//-----------------------------------------------------------------------------------

//function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_perst_phb_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_PHB>&, const PERST_ACTION);

//-----------------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------------

// PCI Nest FIR Register bit26 for SW Freeze enablement
const uint8_t PHB_NFIR_REG_SW_DEFINED_FREEZE = 26;
//Maximum number of iterations (So, 20ms * 100 = 2s before timeout)
const uint32_t MAX_NUM_POLLS = 100;
//(40000000 ns = 20 ms) to wait for PBCQ inbound/outbound to become inactive
const uint64_t NANO_SEC_DELAY = 256;
//400,000 simulation cycles to wait for PBCQ inbound/outbound to become inactive
const uint64_t SIM_CYC_DELAY = 512;

extern "C" {

//-----------------------------------------------------------------------------------
// Function prototype
//-----------------------------------------------------------------------------------
/// @briefF perform read/write to PHB HV register space
/// @param[in] i_target         => phb target
/// @param[in] i_perst_action   => input ACTIVATE or DEACTIVATE to control PERST signal from PHB>
///
/// @return FAPI_RC_SUCCESS if the PERST action completes successfully.
    fapi2::ReturnCode p9_perst_phb(const fapi2::Target<fapi2::TARGET_TYPE_PHB>& i_target,
                                   const PERST_ACTION i_perst_action);

} //extern"C"

#endif //_P9_PERST_PHB_H_
<commit_msg>L3 Update - p9_perst_phb HWP<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_perst_phb.H $      */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_perst_phb.H
/// @brief Procedure to assert/deassert PERST from PHB. (FAPI2)
///
// *HWP HWP Owner: Ricardo Mata Jr. ricmata@us.ibm.com
// *HWP FW Owner: Thi Tran thi@us.ibm.com
// *HWP Team: Nest
// *HWP Level: 3
// *HWP Consumed by: FSP

#ifndef _P9_PERST_PHB_H_
#define _P9_PERST_PHB_H_

//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------
#ifndef _PERST_ACTION_
#define _PERST_ACTION_

enum PERST_ACTION
{
    ACTIVATE_PERST,     //Drive PERST signal active from the PHB. Put in to Reset.
    DEACTIVATE_PERST    //Drive PERST signal inactive from the PHB. Take out of Reset.
};
#endif

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include <fapi2.H>
#include <p9_phb_hv_utils.H>

//-----------------------------------------------------------------------------------
// Structure definitions
//-----------------------------------------------------------------------------------

//function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_perst_phb_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_PHB>&, const PERST_ACTION);

extern "C" {

//-----------------------------------------------------------------------------------
// Function prototype
//-----------------------------------------------------------------------------------
///
/// @brief Assert/deassert PERST signal from PHB.
///
/// @param[in] i_target         => PHB target
/// @param[in] i_perst_action   => Input ACTIVATE or DEACTIVATE
///                                to control PERST signal from PHB.
///
/// @return FAPI_RC_SUCCESS if the PERST action completes successfully, else
///         FAPI2 error code.
///
    fapi2::ReturnCode p9_perst_phb(const fapi2::Target<fapi2::TARGET_TYPE_PHB>& i_target,
                                   const PERST_ACTION i_perst_action);

} //extern"C"

#endif //_P9_PERST_PHB_H_
<|endoftext|>


<commit_before>/*
 *  vaapidisplay.cpp - abstract for VADisplay
 *
 *  Copyright (C) 2014 Intel Corporation
 *    Author: Xu Guangxin <guangxin.xu@intel.com>
 *            Zhao Halley<halley.zhao@intel.com>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1
 *  of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "vaapi/vaapidisplay.h"
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <list>
#include "common/log.h"
#include "common/lock.h"
#include "vaapi/vaapiutils.h"

using std::tr1::weak_ptr;
using std::list;
/**
1. client and yami shares the same display when it provides both native
   display (x11 Display or drm fd) and display type in setNativeDisplay().
   client owns the native display
2. when client set native display type only, yami will create a native
   display and owns it.
3. when client doesn't set any native display, or set display type to
   NATIVE_DISPLAY_AUTO; yami will try to open a x11 display first. if fail,
   drm display will try next

4. A x11 display is compatible to drm display, while not reverse.
   it means, when there is a VADisplay created from x11 display already ,
   yami will not create a new display when drm display is requested,
   simplely reuse the VADisplay.
*/

//helper function
namespace YamiMediaCodec{
static bool vaInit(VADisplay vaDisplay)
{
   int majorVersion, minorVersion;
   VAStatus vaStatus;
   vaStatus= vaInitialize(vaDisplay, &majorVersion, &minorVersion);
   return checkVaapiStatus(vaStatus, "vaInitialize");
}

class NativeDisplayBase {
  public:
    NativeDisplayBase() :m_handle(0) { };
    ~NativeDisplayBase() {};
    virtual bool initialize(const NativeDisplay& display) = 0;
    virtual bool isCompatible (const NativeDisplay& display) = 0;
    intptr_t nativeHandle() {return m_handle;};

  protected:
    virtual bool acceptValidExternalHandle(const NativeDisplay& display) {
        if (display.handle && display.handle != -1) {
            m_handle = display.handle;
            m_selfCreated = false;
            return true;
        }
        return false;
    }
    intptr_t m_handle;
    bool m_selfCreated;

  private:
    DISALLOW_COPY_AND_ASSIGN(NativeDisplayBase);
};

#if __ENABLE_X11__
class NativeDisplayX11 : public NativeDisplayBase{
  public:
    NativeDisplayX11() :NativeDisplayBase(){ };
    virtual ~NativeDisplayX11() {
        if (m_selfCreated && m_handle)
            XCloseDisplay((Display*)(m_handle));
    };

    virtual bool initialize (const NativeDisplay& display) {
        ASSERT(display.type == NATIVE_DISPLAY_X11 || display.type == NATIVE_DISPLAY_AUTO);

        if (acceptValidExternalHandle(display))
            return true;

        m_handle = (intptr_t)XOpenDisplay(NULL);
        m_selfCreated = true;
        return (Display*)m_handle != NULL;
    };

    virtual bool isCompatible(const NativeDisplay& display) {
        if (display.type == NATIVE_DISPLAY_DRM || display.type == NATIVE_DISPLAY_AUTO)
            return true; // x11 is compatile to any drm, (do not consider one X with 2 gfx device)
        if (display.type == NATIVE_DISPLAY_X11 && (!display.handle || display.handle == m_handle))
            return true;
        return false;
    }
};
#endif
class NativeDisplayDrm : public NativeDisplayBase{
  public:
    NativeDisplayDrm() :NativeDisplayBase(){ };
    virtual ~NativeDisplayDrm() {
        if (m_selfCreated && m_handle && m_handle != -1)
            ::close(m_handle);
    };
    virtual bool initialize (const NativeDisplay& display) {
        ASSERT(display.type == NATIVE_DISPLAY_DRM || display.type == NATIVE_DISPLAY_AUTO);

        if (acceptValidExternalHandle(display))
            return true;

        m_handle = open("/dev/dri/card0", O_RDWR);
        m_selfCreated = true;
        return m_handle != -1;
    };

    bool isCompatible(const NativeDisplay& display) {
        if (display.type != NATIVE_DISPLAY_DRM)
            return false;
        if (display.handle == 0 || display.handle == -1 || display.handle == m_handle)
            return true;
        return false;
    }
};

class NativeDisplayVADisplay : public NativeDisplayBase{
  public:
    NativeDisplayVADisplay() :NativeDisplayBase(){ };
    ~NativeDisplayVADisplay() {};
    virtual bool initialize (const NativeDisplay& display) {
        ASSERT(display.type == NATIVE_DISPLAY_VA);

        return acceptValidExternalHandle(display);
    };

    bool isCompatible(const NativeDisplay& display) {
        return display.type == NATIVE_DISPLAY_VA && display.handle == m_handle;
    }
};

typedef SharedPtr<NativeDisplayBase> NativeDisplayPtr;

bool VaapiDisplay::isCompatible(const NativeDisplay& other)
{
    return m_nativeDisplay->isCompatible(other);
}

VaapiDisplay::~VaapiDisplay()
{
    vaTerminate(m_vaDisplay);
}

bool VaapiDisplay::setRotation(int degree)
{
    VAStatus vaStatus;
    VADisplayAttribute rotate;
    rotate.type = VADisplayAttribRotation;
    rotate.value = VA_ROTATION_NONE;
    if (degree == 0)
        rotate.value = VA_ROTATION_NONE;
    else if (degree == 90)
        rotate.value = VA_ROTATION_90;
    else if (degree == 180)
        rotate.value = VA_ROTATION_180;
    else if (degree == 270)
        rotate.value = VA_ROTATION_270;

    vaStatus = vaSetDisplayAttributes(m_vaDisplay, &rotate, 1);
    if (!checkVaapiStatus(vaStatus, "vaSetDisplayAttributes"))
        return false;
    return true;

}

const VAImageFormat *
VaapiDisplay::getVaFormat(uint32_t fourcc)
{
    AutoLock locker(m_lock);
    int i;

    if (m_vaImageFormats.empty()) {
        VAStatus vaStatus;
        int numImageFormats;
        numImageFormats = vaMaxNumImageFormats(m_vaDisplay);
        if (numImageFormats == 0)
            return NULL;

        m_vaImageFormats.reserve(numImageFormats);
        m_vaImageFormats.resize(numImageFormats);

        vaStatus = vaQueryImageFormats(m_vaDisplay, &m_vaImageFormats[0], &numImageFormats);
        checkVaapiStatus(vaStatus, "vaQueryImageFormats()");
        for (i=0; i< m_vaImageFormats.size(); i++)
            DEBUG_FOURCC("supported image format: ", m_vaImageFormats[i].fourcc);
    }

    for (i = 0; i < m_vaImageFormats.size(); i++) {
        VAImageFormat vaImageFormat = m_vaImageFormats[i];
        if (vaImageFormat.fourcc == fourcc)
            return &m_vaImageFormats[i];
    }
    return NULL;
}

//display cache
class DisplayCache
{
public:
    static SharedPtr<DisplayCache> getInstance();
    DisplayPtr createDisplay(const NativeDisplay& nativeDisplay);

    ~DisplayCache() {}
private:
    DisplayCache() {}

    list<weak_ptr<VaapiDisplay> > m_cache;
    YamiMediaCodec::Lock m_lock;
};

SharedPtr<DisplayCache> DisplayCache::getInstance()
{
    static SharedPtr<DisplayCache> cache;
    if (!cache) {
        SharedPtr<DisplayCache> temp(new DisplayCache);
        cache = temp;
    }
    return cache;
}

bool expired(const weak_ptr<VaapiDisplay>& weak)
{
    return !weak.lock();
}

DisplayPtr DisplayCache::createDisplay(const NativeDisplay& nativeDisplay)
{
    NativeDisplayPtr nativeDisplayObj;
    VADisplay vaDisplay = NULL;
    DisplayPtr vaapiDisplay;
    YamiMediaCodec::AutoLock locker(m_lock);

    m_cache.remove_if(expired);

    //lockup first
    list<weak_ptr<VaapiDisplay> >::iterator it;
    for (it = m_cache.begin(); it != m_cache.end(); ++it) {
        vaapiDisplay = (*it).lock();
        if (vaapiDisplay->isCompatible(nativeDisplay)) {
            return vaapiDisplay;
        }
    }
    vaapiDisplay.reset();

    //crate new one
    DEBUG("nativeDisplay: (type : %d), (handle : %ld)", nativeDisplay.type, nativeDisplay.handle);

    switch (nativeDisplay.type) {
    case NATIVE_DISPLAY_AUTO:
#if __ENABLE_X11__
    case NATIVE_DISPLAY_X11:
        nativeDisplayObj.reset (new NativeDisplayX11());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = vaGetDisplay((Display*)(nativeDisplayObj->nativeHandle()));
        if (vaDisplay)
            INFO("use vaapi x11 backend");
        if(vaDisplay || nativeDisplay.type == NATIVE_DISPLAY_X11)
            break;
        INFO("try to init va with x11 display (%p) but failed", (Display*)(nativeDisplayObj->nativeHandle()));
        // NATIVE_DISPLAY_AUTO continue, no break
#endif
    case NATIVE_DISPLAY_DRM:
        nativeDisplayObj.reset (new NativeDisplayDrm());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = vaGetDisplayDRM(nativeDisplayObj->nativeHandle());
        INFO("use vaapi drm backend");
        break;
    case NATIVE_DISPLAY_VA:
        nativeDisplayObj.reset (new NativeDisplayVADisplay());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = (VADisplay)nativeDisplayObj->nativeHandle();
        INFO("use vaapi va backend");
        break;
    default:
        break;
    }

    if (vaDisplay == NULL) {
        ERROR("vaGetDisplay failed.");
        return vaapiDisplay;
    }

    if (nativeDisplay.type == NATIVE_DISPLAY_VA || vaInit(vaDisplay)) {
        DisplayPtr temp(new VaapiDisplay(nativeDisplayObj, vaDisplay));
        vaapiDisplay = temp;
    }
    if (vaapiDisplay) {
        weak_ptr<VaapiDisplay> weak(vaapiDisplay);
        m_cache.push_back(weak);
    }
    return vaapiDisplay;
}

DisplayPtr VaapiDisplay::create(const NativeDisplay& display)
{
    return DisplayCache::getInstance()->createDisplay(display);
}
} //YamiMediaCodec
<commit_msg>when using DRM try /dev/dri/renderD128 before /dev/dri/card0<commit_after>/*
 *  vaapidisplay.cpp - abstract for VADisplay
 *
 *  Copyright (C) 2014 Intel Corporation
 *    Author: Xu Guangxin <guangxin.xu@intel.com>
 *            Zhao Halley<halley.zhao@intel.com>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1
 *  of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "vaapi/vaapidisplay.h"
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <list>
#include "common/log.h"
#include "common/lock.h"
#include "vaapi/vaapiutils.h"

using std::tr1::weak_ptr;
using std::list;
/**
1. client and yami shares the same display when it provides both native
   display (x11 Display or drm fd) and display type in setNativeDisplay().
   client owns the native display
2. when client set native display type only, yami will create a native
   display and owns it.
3. when client doesn't set any native display, or set display type to
   NATIVE_DISPLAY_AUTO; yami will try to open a x11 display first. if fail,
   drm display will try next

4. A x11 display is compatible to drm display, while not reverse.
   it means, when there is a VADisplay created from x11 display already ,
   yami will not create a new display when drm display is requested,
   simplely reuse the VADisplay.
*/

//helper function
namespace YamiMediaCodec{
static bool vaInit(VADisplay vaDisplay)
{
   int majorVersion, minorVersion;
   VAStatus vaStatus;
   vaStatus= vaInitialize(vaDisplay, &majorVersion, &minorVersion);
   return checkVaapiStatus(vaStatus, "vaInitialize");
}

class NativeDisplayBase {
  public:
    NativeDisplayBase() :m_handle(0) { };
    ~NativeDisplayBase() {};
    virtual bool initialize(const NativeDisplay& display) = 0;
    virtual bool isCompatible (const NativeDisplay& display) = 0;
    intptr_t nativeHandle() {return m_handle;};

  protected:
    virtual bool acceptValidExternalHandle(const NativeDisplay& display) {
        if (display.handle && display.handle != -1) {
            m_handle = display.handle;
            m_selfCreated = false;
            return true;
        }
        return false;
    }
    intptr_t m_handle;
    bool m_selfCreated;

  private:
    DISALLOW_COPY_AND_ASSIGN(NativeDisplayBase);
};

#if __ENABLE_X11__
class NativeDisplayX11 : public NativeDisplayBase{
  public:
    NativeDisplayX11() :NativeDisplayBase(){ };
    virtual ~NativeDisplayX11() {
        if (m_selfCreated && m_handle)
            XCloseDisplay((Display*)(m_handle));
    };

    virtual bool initialize (const NativeDisplay& display) {
        ASSERT(display.type == NATIVE_DISPLAY_X11 || display.type == NATIVE_DISPLAY_AUTO);

        if (acceptValidExternalHandle(display))
            return true;

        m_handle = (intptr_t)XOpenDisplay(NULL);
        m_selfCreated = true;
        return (Display*)m_handle != NULL;
    };

    virtual bool isCompatible(const NativeDisplay& display) {
        if (display.type == NATIVE_DISPLAY_DRM || display.type == NATIVE_DISPLAY_AUTO)
            return true; // x11 is compatile to any drm, (do not consider one X with 2 gfx device)
        if (display.type == NATIVE_DISPLAY_X11 && (!display.handle || display.handle == m_handle))
            return true;
        return false;
    }
};
#endif
class NativeDisplayDrm : public NativeDisplayBase{
  public:
    NativeDisplayDrm() :NativeDisplayBase(){ };
    virtual ~NativeDisplayDrm() {
        if (m_selfCreated && m_handle && m_handle != -1)
            ::close(m_handle);
    };
    virtual bool initialize (const NativeDisplay& display) {
        ASSERT(display.type == NATIVE_DISPLAY_DRM || display.type == NATIVE_DISPLAY_AUTO);

        if (acceptValidExternalHandle(display))
            return true;

        m_handle = open("/dev/dri/renderD128", O_RDWR);
        if (m_handle < 0)
            m_handle = open("/dev/dri/card0", O_RDWR);
        m_selfCreated = true;
        return m_handle != -1;
    };

    bool isCompatible(const NativeDisplay& display) {
        if (display.type != NATIVE_DISPLAY_DRM)
            return false;
        if (display.handle == 0 || display.handle == -1 || display.handle == m_handle)
            return true;
        return false;
    }
};

class NativeDisplayVADisplay : public NativeDisplayBase{
  public:
    NativeDisplayVADisplay() :NativeDisplayBase(){ };
    ~NativeDisplayVADisplay() {};
    virtual bool initialize (const NativeDisplay& display) {
        ASSERT(display.type == NATIVE_DISPLAY_VA);

        return acceptValidExternalHandle(display);
    };

    bool isCompatible(const NativeDisplay& display) {
        return display.type == NATIVE_DISPLAY_VA && display.handle == m_handle;
    }
};

typedef SharedPtr<NativeDisplayBase> NativeDisplayPtr;

bool VaapiDisplay::isCompatible(const NativeDisplay& other)
{
    return m_nativeDisplay->isCompatible(other);
}

VaapiDisplay::~VaapiDisplay()
{
    vaTerminate(m_vaDisplay);
}

bool VaapiDisplay::setRotation(int degree)
{
    VAStatus vaStatus;
    VADisplayAttribute rotate;
    rotate.type = VADisplayAttribRotation;
    rotate.value = VA_ROTATION_NONE;
    if (degree == 0)
        rotate.value = VA_ROTATION_NONE;
    else if (degree == 90)
        rotate.value = VA_ROTATION_90;
    else if (degree == 180)
        rotate.value = VA_ROTATION_180;
    else if (degree == 270)
        rotate.value = VA_ROTATION_270;

    vaStatus = vaSetDisplayAttributes(m_vaDisplay, &rotate, 1);
    if (!checkVaapiStatus(vaStatus, "vaSetDisplayAttributes"))
        return false;
    return true;

}

const VAImageFormat *
VaapiDisplay::getVaFormat(uint32_t fourcc)
{
    AutoLock locker(m_lock);
    int i;

    if (m_vaImageFormats.empty()) {
        VAStatus vaStatus;
        int numImageFormats;
        numImageFormats = vaMaxNumImageFormats(m_vaDisplay);
        if (numImageFormats == 0)
            return NULL;

        m_vaImageFormats.reserve(numImageFormats);
        m_vaImageFormats.resize(numImageFormats);

        vaStatus = vaQueryImageFormats(m_vaDisplay, &m_vaImageFormats[0], &numImageFormats);
        checkVaapiStatus(vaStatus, "vaQueryImageFormats()");
        for (i=0; i< m_vaImageFormats.size(); i++)
            DEBUG_FOURCC("supported image format: ", m_vaImageFormats[i].fourcc);
    }

    for (i = 0; i < m_vaImageFormats.size(); i++) {
        VAImageFormat vaImageFormat = m_vaImageFormats[i];
        if (vaImageFormat.fourcc == fourcc)
            return &m_vaImageFormats[i];
    }
    return NULL;
}

//display cache
class DisplayCache
{
public:
    static SharedPtr<DisplayCache> getInstance();
    DisplayPtr createDisplay(const NativeDisplay& nativeDisplay);

    ~DisplayCache() {}
private:
    DisplayCache() {}

    list<weak_ptr<VaapiDisplay> > m_cache;
    YamiMediaCodec::Lock m_lock;
};

SharedPtr<DisplayCache> DisplayCache::getInstance()
{
    static SharedPtr<DisplayCache> cache;
    if (!cache) {
        SharedPtr<DisplayCache> temp(new DisplayCache);
        cache = temp;
    }
    return cache;
}

bool expired(const weak_ptr<VaapiDisplay>& weak)
{
    return !weak.lock();
}

DisplayPtr DisplayCache::createDisplay(const NativeDisplay& nativeDisplay)
{
    NativeDisplayPtr nativeDisplayObj;
    VADisplay vaDisplay = NULL;
    DisplayPtr vaapiDisplay;
    YamiMediaCodec::AutoLock locker(m_lock);

    m_cache.remove_if(expired);

    //lockup first
    list<weak_ptr<VaapiDisplay> >::iterator it;
    for (it = m_cache.begin(); it != m_cache.end(); ++it) {
        vaapiDisplay = (*it).lock();
        if (vaapiDisplay->isCompatible(nativeDisplay)) {
            return vaapiDisplay;
        }
    }
    vaapiDisplay.reset();

    //crate new one
    DEBUG("nativeDisplay: (type : %d), (handle : %ld)", nativeDisplay.type, nativeDisplay.handle);

    switch (nativeDisplay.type) {
    case NATIVE_DISPLAY_AUTO:
#if __ENABLE_X11__
    case NATIVE_DISPLAY_X11:
        nativeDisplayObj.reset (new NativeDisplayX11());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = vaGetDisplay((Display*)(nativeDisplayObj->nativeHandle()));
        if (vaDisplay)
            INFO("use vaapi x11 backend");
        if(vaDisplay || nativeDisplay.type == NATIVE_DISPLAY_X11)
            break;
        INFO("try to init va with x11 display (%p) but failed", (Display*)(nativeDisplayObj->nativeHandle()));
        // NATIVE_DISPLAY_AUTO continue, no break
#endif
    case NATIVE_DISPLAY_DRM:
        nativeDisplayObj.reset (new NativeDisplayDrm());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = vaGetDisplayDRM(nativeDisplayObj->nativeHandle());
        INFO("use vaapi drm backend");
        break;
    case NATIVE_DISPLAY_VA:
        nativeDisplayObj.reset (new NativeDisplayVADisplay());
        if (nativeDisplayObj && nativeDisplayObj->initialize(nativeDisplay))
            vaDisplay = (VADisplay)nativeDisplayObj->nativeHandle();
        INFO("use vaapi va backend");
        break;
    default:
        break;
    }

    if (vaDisplay == NULL) {
        ERROR("vaGetDisplay failed.");
        return vaapiDisplay;
    }

    if (nativeDisplay.type == NATIVE_DISPLAY_VA || vaInit(vaDisplay)) {
        DisplayPtr temp(new VaapiDisplay(nativeDisplayObj, vaDisplay));
        vaapiDisplay = temp;
    }
    if (vaapiDisplay) {
        weak_ptr<VaapiDisplay> weak(vaapiDisplay);
        m_cache.push_back(weak);
    }
    return vaapiDisplay;
}

DisplayPtr VaapiDisplay::create(const NativeDisplay& display)
{
    return DisplayCache::getInstance()->createDisplay(display);
}
} //YamiMediaCodec
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "Game.h"
#include "EntityManager.h"
#include "RenderMap.h"
#include "PositionMap.h"
#include "CollisionMap.h"
#include "TextureManager.h"
#include <sstream>
#include <cstdlib>

/*
_______________________________________
---------------TODO LIST---------------
_______________________________________

1. Pan and zoom
2. User interface
3. player object
4. projectile object
5. game states
6. main menu
7. in-game menu
8. maps - static and procdually generated

_______________________________________
-----------------IDEAS-----------------
_______________________________________

gavity field view
-many vectors (drawn as lines) that show gravy field on map
-dotted line trails for objects

*/

void Game::start() {

	_mainWindow.create(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32), "Title");

	gameLoop();

	_mainWindow.close();
}

sf::RenderWindow& Game::GetWindow() {
	return Game::_mainWindow;
}

RenderMap& Game::getRenderMap() {
	return Game::_renderMap;
}

PositionMap& Game::getPositionMap() {
	return _positionMap;
}

CollisionMap& Game::getCollisionMap() {
	return _collisionMap;
}

TextureManager& Game::getTextureManager() {
	return _textureManager;
}

EntityManager& Game::getEntityManager() {
	return _entityManager;
}

int Game::getScreenWidth() {
	return Game::_mainWindow.getSize().x;
}

int Game::getScreenHeight() {
	return Game::_mainWindow.getSize().y;
}

void Game::gameLoop() {

	for (int i = 0; i < 30; i++){
		int x = rand() % 1000;
		int y = rand() % 700;
		_entityManager.addPlanetEntity(sf::Vector2f(x, y), sf::Vector2f(x/100, y/100), 500, 5);
	}

	while (GetWindow().isOpen())
    {
        sf::Event event;
        while (GetWindow().pollEvent(event))
        {
           switch (event.type) {
				case sf::Event::Closed:
					GetWindow().close();
					break;
			}
        }

        GetWindow().clear();

		auto deltaTime = _clock.restart();
		_positionMap.updateGravity();
		_collisionMap.resolveCollisions();
		_positionMap.updateComponents(deltaTime.asSeconds());
		_renderMap.drawAll();

        GetWindow().display();

		//update title
		ostringstream ss;
		ss << 1/deltaTime.asSeconds();
		string s1(ss.str());
		ostringstream sss;
		sss << _entityManager.numEntities();
		string s2(sss.str());
		string s("Title " + s1 + "  " + s2);
		GetWindow().setTitle(s);
    }

}

sf::RenderWindow Game::_mainWindow;
sf::Clock Game::_clock;
EntityManager  Game::_entityManager;
RenderMap  Game::_renderMap;
PositionMap Game::_positionMap;
CollisionMap Game::_collisionMap;
TextureManager Game::_textureManager;<commit_msg>Disabled title bar information<commit_after>#include "stdafx.h"
#include "Game.h"
#include "EntityManager.h"
#include "RenderMap.h"
#include "PositionMap.h"
#include "CollisionMap.h"
#include "TextureManager.h"
#include <sstream>
#include <cstdlib>

/*
_______________________________________
---------------TODO LIST---------------
_______________________________________

1. Pan and zoom
2. User interface
3. player object
4. projectile object
5. game states
6. main menu
7. in-game menu
8. maps - static and procdually generated

_______________________________________
-----------------IDEAS-----------------
_______________________________________

gavity field view
-many vectors (drawn as lines) that show gravy field on map
-dotted line trails for objects

*/

void Game::start() {

	_mainWindow.create(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32), "Title");

	gameLoop();

	_mainWindow.close();
}

sf::RenderWindow& Game::GetWindow() {
	return Game::_mainWindow;
}

RenderMap& Game::getRenderMap() {
	return Game::_renderMap;
}

PositionMap& Game::getPositionMap() {
	return _positionMap;
}

CollisionMap& Game::getCollisionMap() {
	return _collisionMap;
}

TextureManager& Game::getTextureManager() {
	return _textureManager;
}

EntityManager& Game::getEntityManager() {
	return _entityManager;
}

int Game::getScreenWidth() {
	return Game::_mainWindow.getSize().x;
}

int Game::getScreenHeight() {
	return Game::_mainWindow.getSize().y;
}

void Game::gameLoop() {

	for (int i = 0; i < 30; i++){
		int x = rand() % 1000;
		int y = rand() % 700;
		_entityManager.addPlanetEntity(sf::Vector2f(x, y), sf::Vector2f(x/100, y/100), 500, 5);
	}

	while (GetWindow().isOpen())
    {
        sf::Event event;
        while (GetWindow().pollEvent(event))
        {
           switch (event.type) {
				case sf::Event::Closed:
					GetWindow().close();
					break;
			}
        }

        GetWindow().clear();

		auto deltaTime = _clock.restart();
		_positionMap.updateGravity();
		_collisionMap.resolveCollisions();
		_positionMap.updateComponents(deltaTime.asSeconds());
		_renderMap.drawAll();

        GetWindow().display();

		//update title
		/*
		ostringstream ss;
		ss << 1/deltaTime.asSeconds();
		string s1(ss.str());
		ostringstream sss;
		sss << _entityManager.numEntities();
		string s2(sss.str());
		string s("Title " + s1 + "  " + s2);
		GetWindow().setTitle(s);
		*/
    }

}

sf::RenderWindow Game::_mainWindow;
sf::Clock Game::_clock;
EntityManager  Game::_entityManager;
RenderMap  Game::_renderMap;
PositionMap Game::_positionMap;
CollisionMap Game::_collisionMap;
TextureManager Game::_textureManager;<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <fstream>
#include <mpd/client.h>
#include <taglib/fileref.h>
#include "consumer.hh"
#include "globals.hh"

Consumer::Consumer(std::string&& throwaway)
    : _playlist_file_(std::move(throwaway))
    , _write_to_file_(true) {

    std::ifstream file(_playlist_file_);

    if (file) {
        std::string temp;
        while (getline(file, temp)) {
            _playlist_lines_.insert(temp);
        }
    }
}

void Consumer::_sorted_insert_song_(const std::string& str) {
    bool inserted = _playlist_lines_.insert(str).second;
    if (NONO && inserted) {
        std::printf("Insert `%s` into playlist `%s`.\n", str.c_str(),
                    _playlist_file_.c_str());
    }
}

Consumer::~Consumer() {
    if (_write_to_file_) {
        if (!NONO) {
            if (auto file = std::ofstream(_playlist_file_)) {
                for (const auto& s : _playlist_lines_) {
                    file << s << '\n';
                }
                if (USE_MPD) {
                    _run_mpd_();
                }
            } else {
                std::fprintf(stderr,
                             "Problem opening file %s!\nAborting!\n",
                             _playlist_file_.c_str());
                std::exit(EXIT_FAILURE);
            }
        } else if (USE_MPD) {
            std::printf("Will clear the mpd playlist, update the mpd "
                        "database, and load %s.\n",
                        boost::filesystem::path(_playlist_file_)
                            .filename()
                            .replace_extension()
                            .c_str());
        }
    }
}

void Consumer::_apply_tags_(const boost::filesystem::path& path,
                            const std::string& artist,
                            const std::string& title) {
    bool changed = false;

    TagLib::FileRef file(path.c_str());
    TagLib::Tag* tags = file.tag();

    if (!tags) {
        std::fprintf(stderr, "Music file `%s` has no tags!\n",
                     path.c_str());
        return;
    }

    if (tags->artist() != artist) {
        if (NONO) {
            std::printf("  Artist: `%s` -> `%s`\n",
                        tags->artist().toCString(), artist.c_str());
        } else {
            changed = true;
            tags->setArtist(artist);
        }
    }

    if (tags->title() != title) {
        if (NONO) {
            std::printf("  Title: `%s` -> `%s`\n",
                        tags->title().toCString(), title.c_str());
        } else {
            changed = true;
            tags->setTitle(title);
        }
    }

    if (changed) {
        file.save();
    }
}
<commit_msg>Reinvent ifstream and ofstream to increase performance.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <mpd/client.h>
#include <taglib/fileref.h>
#include <stdexcept>

#include "consumer.hh"
#include "globals.hh"

struct ifstream {
    std::FILE* file;

    explicit ifstream(const char* path) {
        file = std::fopen(path, "r");
    }
    ~ifstream() noexcept { std::fclose(file); }
    ifstream(const ifstream&) = delete;
    ifstream& operator=(const ifstream&) = delete;

    bool read_line(std::string& other) {
        other.clear();
        for (int c = std::fgetc(file); c != EOF;
             c = std::fgetc(file)) {
            if (c == int('\n')) {
                return true;
            } else {
                other += char(c);
            }
        }
        return false;
    }

    operator bool() noexcept { return file; }
};

struct ofstream {
    std::FILE* file;

    explicit ofstream(const char* path) {
        file = std::fopen(path, "w");
    }
    ~ofstream() noexcept { std::fclose(file); }
    ofstream(ofstream&& other) noexcept : file(nullptr) {
        *this = std::move(other);
    }
    ofstream& operator=(ofstream&& other) noexcept {
        std::swap(file, other.file);
        return *this;
    }

    bool write(const char* str) noexcept {
        return std::fputs(str, file) != EOF;
    }

    bool write(char c) noexcept {
        return std::fputc(c, file) != EOF;
    }

    operator bool() noexcept { return file; }
};

Consumer::Consumer(std::string&& throwaway)
    : _playlist_file_(std::move(throwaway))
    , _write_to_file_(true) {

    ifstream file(_playlist_file_.c_str());

    if (file) {
        std::string temp;
        while (file.read_line(temp)) {
            _playlist_lines_.insert(temp);
        }
    }
}

void Consumer::_sorted_insert_song_(const std::string& str) {
    bool inserted = _playlist_lines_.insert(str).second;
    if (NONO && inserted) {
        std::printf("Insert `%s` into playlist `%s`.\n", str.c_str(),
                    _playlist_file_.c_str());
    }
}

Consumer::~Consumer() {
    if (_write_to_file_) {
        if (!NONO) {
            if (auto file = ofstream(_playlist_file_.c_str())) {
                for (const auto& s : _playlist_lines_) {
                    if (!(file.write(s.c_str()) &&
                          file.write('\n'))) {
                        throw std::runtime_error(
                            "In ofstream::write: Error writing to "
                            "playlist file.");
                    }
                }
                if (USE_MPD) {
                    _run_mpd_();
                }
            } else {
                std::fprintf(stderr,
                             "Problem opening file %s!\nAborting!\n",
                             _playlist_file_.c_str());
                std::exit(EXIT_FAILURE);
            }
        } else if (USE_MPD) {
            std::printf("Will clear the mpd playlist, update the mpd "
                        "database, and load %s.\n",
                        boost::filesystem::path(_playlist_file_)
                            .filename()
                            .replace_extension()
                            .c_str());
        }
    }
}

void Consumer::_apply_tags_(const boost::filesystem::path& path,
                            const std::string& artist,
                            const std::string& title) {
    bool changed = false;

    TagLib::FileRef file(path.c_str());
    TagLib::Tag* tags = file.tag();

    if (!tags) {
        std::fprintf(stderr, "Music file `%s` has no tags!\n",
                     path.c_str());
        return;
    }

    if (tags->artist() != artist) {
        if (NONO) {
            std::printf("  Artist: `%s` -> `%s`\n",
                        tags->artist().toCString(), artist.c_str());
        } else {
            changed = true;
            tags->setArtist(artist);
        }
    }

    if (tags->title() != title) {
        if (NONO) {
            std::printf("  Title: `%s` -> `%s`\n",
                        tags->title().toCString(), title.c_str());
        } else {
            changed = true;
            tags->setTitle(title);
        }
    }

    if (changed) {
        file.save();
    }
}
<|endoftext|>


<commit_before>/*
Copyright 2017 Intel Corporation

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 <stdio.h>

#include "PresentMon.hpp"

namespace {

bool CombineArguments(
    int argc,
    char** argv,
    char* out,
    size_t outSize)
{
    size_t idx = 0;
    for (int i = 1; i < argc && idx < outSize; ++i) {
        if (idx >= outSize) {
            return false; // was truncated
        }

        if (argv[i][0] != '\"' && strchr(argv[i], ' ')) {
            idx += snprintf(out + idx, outSize - idx, " \"%s\"", argv[i]);
        } else {
            idx += snprintf(out + idx, outSize - idx, " %s", argv[i]);
        }
    }

    return true;
}

bool ParseModifier(char* arg, UINT* inoutModifier)
{
    struct {
        char const* arg;
        UINT modifier;
    } options[] = {
        { "alt",     MOD_ALT     },
        { "control", MOD_CONTROL },
        { "ctrl",    MOD_CONTROL },
        { "shift",   MOD_SHIFT   },
        { "sh",      MOD_SHIFT   },
        { "windows", MOD_WIN     },
        { "win",     MOD_WIN     },
    };

    for (size_t i = 0, N = _countof(options); i < N; ++i) {
        if (_stricmp(arg, options[i].arg) == 0) {
            *inoutModifier |= options[i].modifier;
            return true;
        }
    }

    return false;
}

bool ParseKeyCode(char* arg, UINT* outKeyCode)
{
#define CHECK_KEY(_Arg, _Code) \
    if (_stricmp(arg, _Arg) == 0) { *outKeyCode = _Code; return true; }
    CHECK_KEY("BACKSPACE", VK_BACK)
    CHECK_KEY("TAB", VK_TAB)
    CHECK_KEY("CLEAR", VK_CLEAR)
    CHECK_KEY("ENTER", VK_RETURN)
    CHECK_KEY("PAUSE", VK_PAUSE)
    CHECK_KEY("CAPSLOCK", VK_CAPITAL)
    CHECK_KEY("ESC", VK_ESCAPE)
    CHECK_KEY("SPACE", VK_SPACE)
    CHECK_KEY("PAGEUP", VK_PRIOR)
    CHECK_KEY("PAGEDOWN", VK_NEXT)
    CHECK_KEY("END", VK_END)
    CHECK_KEY("HOME", VK_HOME)
    CHECK_KEY("LEFT", VK_LEFT)
    CHECK_KEY("UP", VK_UP)
    CHECK_KEY("RIGHT", VK_RIGHT)
    CHECK_KEY("DOWN", VK_DOWN)
    CHECK_KEY("PRINTSCREEN", VK_SNAPSHOT)
    CHECK_KEY("INS", VK_INSERT)
    CHECK_KEY("DEL", VK_DELETE)
    CHECK_KEY("HELP", VK_HELP)
    CHECK_KEY("0", 0x30)
    CHECK_KEY("1", 0x31)
    CHECK_KEY("2", 0x32)
    CHECK_KEY("3", 0x33)
    CHECK_KEY("4", 0x34)
    CHECK_KEY("5", 0x35)
    CHECK_KEY("6", 0x36)
    CHECK_KEY("7", 0x37)
    CHECK_KEY("8", 0x38)
    CHECK_KEY("9", 0x39)
    CHECK_KEY("A", 0x42)
    CHECK_KEY("B", 0x43)
    CHECK_KEY("C", 0x44)
    CHECK_KEY("D", 0x45)
    CHECK_KEY("E", 0x46)
    CHECK_KEY("F", 0x47)
    CHECK_KEY("G", 0x48)
    CHECK_KEY("H", 0x49)
    CHECK_KEY("I", 0x4A)
    CHECK_KEY("J", 0x4B)
    CHECK_KEY("K", 0x4C)
    CHECK_KEY("L", 0x4D)
    CHECK_KEY("M", 0x4E)
    CHECK_KEY("N", 0x4F)
    CHECK_KEY("O", 0x50)
    CHECK_KEY("P", 0x51)
    CHECK_KEY("Q", 0x52)
    CHECK_KEY("R", 0x53)
    CHECK_KEY("S", 0x54)
    CHECK_KEY("T", 0x55)
    CHECK_KEY("U", 0x56)
    CHECK_KEY("V", 0x57)
    CHECK_KEY("W", 0x58)
    CHECK_KEY("X", 0x59)
    CHECK_KEY("Y", 0x5A)
    CHECK_KEY("Num0", VK_NUMPAD0)
    CHECK_KEY("Num1", VK_NUMPAD1)
    CHECK_KEY("Num2", VK_NUMPAD2)
    CHECK_KEY("Num3", VK_NUMPAD3)
    CHECK_KEY("Num4", VK_NUMPAD4)
    CHECK_KEY("Num5", VK_NUMPAD5)
    CHECK_KEY("Num6", VK_NUMPAD6)
    CHECK_KEY("Num7", VK_NUMPAD7)
    CHECK_KEY("Num8", VK_NUMPAD8)
    CHECK_KEY("Num9", VK_NUMPAD9)
    CHECK_KEY("Multiply", VK_MULTIPLY)
    CHECK_KEY("Add", VK_ADD)
    CHECK_KEY("Separator", VK_SEPARATOR)
    CHECK_KEY("Subtract", VK_SUBTRACT)
    CHECK_KEY("Decimal", VK_DECIMAL)
    CHECK_KEY("Divide", VK_DIVIDE)
    CHECK_KEY("F1", VK_F1)
    CHECK_KEY("F2", VK_F2)
    CHECK_KEY("F3", VK_F3)
    CHECK_KEY("F4", VK_F4)
    CHECK_KEY("F5", VK_F5)
    CHECK_KEY("F6", VK_F6)
    CHECK_KEY("F7", VK_F7)
    CHECK_KEY("F8", VK_F8)
    CHECK_KEY("F9", VK_F9)
    CHECK_KEY("F10", VK_F10)
    CHECK_KEY("F11", VK_F11)
    CHECK_KEY("F12", VK_F12)
    CHECK_KEY("F13", VK_F13)
    CHECK_KEY("F14", VK_F14)
    CHECK_KEY("F15", VK_F15)
    CHECK_KEY("F16", VK_F16)
    CHECK_KEY("F17", VK_F17)
    CHECK_KEY("F18", VK_F18)
    CHECK_KEY("F19", VK_F19)
    CHECK_KEY("F20", VK_F20)
    CHECK_KEY("F21", VK_F21)
    CHECK_KEY("F22", VK_F22)
    CHECK_KEY("F23", VK_F23)
    CHECK_KEY("F24", VK_F24)
    CHECK_KEY("NUMLOCK", VK_NUMLOCK)
    CHECK_KEY("SCROLLLOCK", VK_SCROLL)

    return false;
}

void AssignHotkey(int* inoutArgIdx, int argc, char** argv, CommandLineArgs* args)
{
    auto argIdx = *inoutArgIdx;

    args->mHotkeySupport = true;
    if (++argIdx == argc) {
        return;
    }

#pragma warning(suppress: 4996)
    auto token = strtok(argv[argIdx], "+");
    for (;;) {
        auto prev = token;
#pragma warning(suppress: 4996)
        token = strtok(nullptr, "+");
        if (token == nullptr) {
            if (!ParseKeyCode(prev, &args->mHotkeyVirtualKeyCode)) {
                return;
            }
            break;
        }

        if (!ParseModifier(prev, &args->mHotkeyModifiers)) {
            return;
        }
    }

    *inoutArgIdx = argIdx;
}

UINT atou(char const* a)
{
    int i = atoi(a);
    return i <= 0 ? 0 : (UINT) i;
}

void PrintHelp()
{
    // NOTE: remember to update README.md when modifying usage
    fprintf(stderr,
        "PresentMon version 1.1.1\n"
        "\n"
        "Capture target options:\n"
        "    -captureall                Record all processes (default).\n"
        "    -process_name [exe name]   Record specific process specified by name.\n"
        "    -process_id [integer]      Record specific process specified by ID.\n"
        "\n"
        "Output options:\n"
        "    -no_csv                    Do not create any output file.\n"
        "    -output_file [path]        Write CSV output to specified path. Otherwise, the default is\n"
        "                               PresentMon-PROCESSNAME-TIME.csv.\n"
        "\n"
        "Control and filtering options:\n"
        "    -etl_file [path]           Consume events from an ETL file instead of a running process.\n"
        "    -scroll_toggle             Only record events while scroll lock is enabled.\n"
        "    -scroll_indicator          Set scroll lock while recording events.\n"
        "    -hotkey [key]              Use specified key to start and stop recording, writing to a\n"
        "                               unique file each time (default is F11).\n"
        "    -delay [seconds]           Wait for specified time before starting to record. When using\n"
        "                               -hotkey, delay occurs each time recording is started.\n"
        "    -timed [seconds]           Stop recording after the specified amount of time.  PresentMon will exit\n"
        "                               timer expires.\n"
        "    -exclude_dropped           Exclude dropped presents from the csv output.\n"
        "    -terminate_on_proc_exit    Terminate PresentMon when all instances of the specified process exit.\n"
        "    -terminate_after_timed     Terminate PresentMon after the timed trace, specified using -timed, completes.\n"
        "    -simple                    Disable advanced tracking (try this if you encounter crashes).\n"
        "    -dont_restart_as_admin     Don't try to elevate privilege.\n"
        "    -no_top                    Don't display active swap chains in the console window.\n"
        );
}

}

bool ParseCommandLine(int argc, char** argv, CommandLineArgs* args)
{
    for (int i = 1; i < argc; ++i) {
#define ARG1(Arg, Assign) \
        if (strcmp(argv[i], Arg) == 0) { \
            Assign; \
            continue; \
        }

#define ARG2(Arg, Assign) \
        if (strcmp(argv[i], Arg) == 0) { \
            if (++i < argc) { \
                Assign; \
                continue; \
            } \
            fprintf(stderr, "error: %s expecting argument.\n", Arg); \
        }

        // Capture target options
             ARG1("-captureall",             args->mTargetProcessName   = nullptr)
        else ARG2("-process_name",           args->mTargetProcessName   = argv[i])
        else ARG2("-process_id",             args->mTargetPid           = atou(argv[i]))
        else ARG2("-etl_file",               args->mEtlFileName         = argv[i])

        // Output options
        else ARG1("-no_csv",                 args->mOutputFile          = false)
        else ARG2("-output_file",            args->mOutputFileName      = argv[i])

        // Control and filtering options
        else ARG1("-hotkey",                 AssignHotkey(&i, argc, argv, args))
        else ARG1("-scroll_toggle",          args->mScrollLockToggle    = true)
        else ARG1("-scroll_indicator",       args->mScrollLockIndicator = true)
        else ARG2("-delay",                  args->mDelay               = atou(argv[i]))
        else ARG2("-timed",                  args->mTimer               = atou(argv[i]))
        else ARG1("-exclude_dropped",        args->mExcludeDropped      = true)
        else ARG1("-terminate_on_proc_exit", args->mTerminateOnProcExit = true)
        else ARG1("-terminate_after_timed",  args->mTerminateAfterTimer = true)
        else ARG1("-simple",                 args->mSimple              = true)
        else ARG1("-dont_restart_as_admin",  args->mTryToElevate        = false)
        else ARG1("-no_top",                 args->mSimpleConsole       = true)

        // Provided argument wasn't recognized
        else fprintf(stderr, "error: %s '%s'.\n",
            i > 0 && strcmp(argv[i - 1], "-hotkey") == 0 ? "failed to parse hotkey" : "unrecognized argument",
            argv[i]);

        PrintHelp();
        return false;
    }

    // Validate command line arguments
    if (((args->mTargetProcessName == nullptr) ? 0 : 1) +
        ((args->mTargetPid         <= 0      ) ? 0 : 1) > 1) {
        fprintf(stderr, "error: only specify one of -captureall, -process_name, or -process_id.\n");
        PrintHelp();
        return false;
    }

    if (args->mEtlFileName && args->mHotkeySupport) {
        fprintf(stderr, "error: -etl_file and -hotkey arguments are not compatible.\n");
        PrintHelp();
        return false;
    }

    if (args->mHotkeySupport) {
        if ((args->mHotkeyModifiers & MOD_CONTROL) != 0 && args->mHotkeyVirtualKeyCode == 0x44 /*C*/) {
            fprintf(stderr, "error: 'CTRL+C' cannot be used as a -hotkey, it is reserved for terminating the trace.\n");
            PrintHelp();
            return false;
        }

        if (args->mHotkeyModifiers == MOD_NOREPEAT && args->mHotkeyVirtualKeyCode == VK_F12) {
            fprintf(stderr, "error: 'F12' cannot be used as a -hotkey, it is reserved for the debugger.\n");
            PrintHelp();
            return false;
        }
    }

    return true;
}

bool RestartAsAdministrator(
    int argc,
    char** argv)
{
    char exe_path[MAX_PATH] = {};
    GetModuleFileNameA(NULL, exe_path, sizeof(exe_path));

    char args[MAX_PATH] = {};
    if (!CombineArguments(argc, argv, args, MAX_PATH)) {
        return false;
    }

    ShellExecuteA(NULL, "runas", exe_path, args, NULL, SW_SHOW);
    return true;
}

void SetConsoleTitle(
    int argc,
    char** argv)
{
    char args[MAX_PATH] = {};
    size_t idx = snprintf(args, MAX_PATH, "PresentMon");
    if (!CombineArguments(argc, argv, args + idx, MAX_PATH - idx)) {
        args[MAX_PATH - 4] = '.';
        args[MAX_PATH - 3] = '.';
        args[MAX_PATH - 2] = '.';
    }

    SetConsoleTitleA(args);
}

bool EnableScrollLock(bool enable)
{
    auto enabled = (GetKeyState(VK_SCROLL) & 1) == 1;
    if (enabled != enable) {
        auto extraInfo = GetMessageExtraInfo();
        INPUT input[2] = {};

        input[0].type = INPUT_KEYBOARD;
        input[0].ki.wVk = VK_SCROLL;
        input[0].ki.dwExtraInfo = extraInfo;

        input[1].type = INPUT_KEYBOARD;
        input[1].ki.wVk = VK_SCROLL;
        input[1].ki.dwFlags = KEYEVENTF_KEYUP;
        input[1].ki.dwExtraInfo = extraInfo;

        auto sendCount = SendInput(2, input, sizeof(INPUT));
        if (sendCount != 2) {
            fprintf(stderr, "warning: could not toggle scroll lock.\n");
        }
    }

    return enabled;
}

<commit_msg>Update version to v1.1.2<commit_after>/*
Copyright 2017 Intel Corporation

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 <stdio.h>

#include "PresentMon.hpp"

namespace {

bool CombineArguments(
    int argc,
    char** argv,
    char* out,
    size_t outSize)
{
    size_t idx = 0;
    for (int i = 1; i < argc && idx < outSize; ++i) {
        if (idx >= outSize) {
            return false; // was truncated
        }

        if (argv[i][0] != '\"' && strchr(argv[i], ' ')) {
            idx += snprintf(out + idx, outSize - idx, " \"%s\"", argv[i]);
        } else {
            idx += snprintf(out + idx, outSize - idx, " %s", argv[i]);
        }
    }

    return true;
}

bool ParseModifier(char* arg, UINT* inoutModifier)
{
    struct {
        char const* arg;
        UINT modifier;
    } options[] = {
        { "alt",     MOD_ALT     },
        { "control", MOD_CONTROL },
        { "ctrl",    MOD_CONTROL },
        { "shift",   MOD_SHIFT   },
        { "sh",      MOD_SHIFT   },
        { "windows", MOD_WIN     },
        { "win",     MOD_WIN     },
    };

    for (size_t i = 0, N = _countof(options); i < N; ++i) {
        if (_stricmp(arg, options[i].arg) == 0) {
            *inoutModifier |= options[i].modifier;
            return true;
        }
    }

    return false;
}

bool ParseKeyCode(char* arg, UINT* outKeyCode)
{
#define CHECK_KEY(_Arg, _Code) \
    if (_stricmp(arg, _Arg) == 0) { *outKeyCode = _Code; return true; }
    CHECK_KEY("BACKSPACE", VK_BACK)
    CHECK_KEY("TAB", VK_TAB)
    CHECK_KEY("CLEAR", VK_CLEAR)
    CHECK_KEY("ENTER", VK_RETURN)
    CHECK_KEY("PAUSE", VK_PAUSE)
    CHECK_KEY("CAPSLOCK", VK_CAPITAL)
    CHECK_KEY("ESC", VK_ESCAPE)
    CHECK_KEY("SPACE", VK_SPACE)
    CHECK_KEY("PAGEUP", VK_PRIOR)
    CHECK_KEY("PAGEDOWN", VK_NEXT)
    CHECK_KEY("END", VK_END)
    CHECK_KEY("HOME", VK_HOME)
    CHECK_KEY("LEFT", VK_LEFT)
    CHECK_KEY("UP", VK_UP)
    CHECK_KEY("RIGHT", VK_RIGHT)
    CHECK_KEY("DOWN", VK_DOWN)
    CHECK_KEY("PRINTSCREEN", VK_SNAPSHOT)
    CHECK_KEY("INS", VK_INSERT)
    CHECK_KEY("DEL", VK_DELETE)
    CHECK_KEY("HELP", VK_HELP)
    CHECK_KEY("0", 0x30)
    CHECK_KEY("1", 0x31)
    CHECK_KEY("2", 0x32)
    CHECK_KEY("3", 0x33)
    CHECK_KEY("4", 0x34)
    CHECK_KEY("5", 0x35)
    CHECK_KEY("6", 0x36)
    CHECK_KEY("7", 0x37)
    CHECK_KEY("8", 0x38)
    CHECK_KEY("9", 0x39)
    CHECK_KEY("A", 0x42)
    CHECK_KEY("B", 0x43)
    CHECK_KEY("C", 0x44)
    CHECK_KEY("D", 0x45)
    CHECK_KEY("E", 0x46)
    CHECK_KEY("F", 0x47)
    CHECK_KEY("G", 0x48)
    CHECK_KEY("H", 0x49)
    CHECK_KEY("I", 0x4A)
    CHECK_KEY("J", 0x4B)
    CHECK_KEY("K", 0x4C)
    CHECK_KEY("L", 0x4D)
    CHECK_KEY("M", 0x4E)
    CHECK_KEY("N", 0x4F)
    CHECK_KEY("O", 0x50)
    CHECK_KEY("P", 0x51)
    CHECK_KEY("Q", 0x52)
    CHECK_KEY("R", 0x53)
    CHECK_KEY("S", 0x54)
    CHECK_KEY("T", 0x55)
    CHECK_KEY("U", 0x56)
    CHECK_KEY("V", 0x57)
    CHECK_KEY("W", 0x58)
    CHECK_KEY("X", 0x59)
    CHECK_KEY("Y", 0x5A)
    CHECK_KEY("Num0", VK_NUMPAD0)
    CHECK_KEY("Num1", VK_NUMPAD1)
    CHECK_KEY("Num2", VK_NUMPAD2)
    CHECK_KEY("Num3", VK_NUMPAD3)
    CHECK_KEY("Num4", VK_NUMPAD4)
    CHECK_KEY("Num5", VK_NUMPAD5)
    CHECK_KEY("Num6", VK_NUMPAD6)
    CHECK_KEY("Num7", VK_NUMPAD7)
    CHECK_KEY("Num8", VK_NUMPAD8)
    CHECK_KEY("Num9", VK_NUMPAD9)
    CHECK_KEY("Multiply", VK_MULTIPLY)
    CHECK_KEY("Add", VK_ADD)
    CHECK_KEY("Separator", VK_SEPARATOR)
    CHECK_KEY("Subtract", VK_SUBTRACT)
    CHECK_KEY("Decimal", VK_DECIMAL)
    CHECK_KEY("Divide", VK_DIVIDE)
    CHECK_KEY("F1", VK_F1)
    CHECK_KEY("F2", VK_F2)
    CHECK_KEY("F3", VK_F3)
    CHECK_KEY("F4", VK_F4)
    CHECK_KEY("F5", VK_F5)
    CHECK_KEY("F6", VK_F6)
    CHECK_KEY("F7", VK_F7)
    CHECK_KEY("F8", VK_F8)
    CHECK_KEY("F9", VK_F9)
    CHECK_KEY("F10", VK_F10)
    CHECK_KEY("F11", VK_F11)
    CHECK_KEY("F12", VK_F12)
    CHECK_KEY("F13", VK_F13)
    CHECK_KEY("F14", VK_F14)
    CHECK_KEY("F15", VK_F15)
    CHECK_KEY("F16", VK_F16)
    CHECK_KEY("F17", VK_F17)
    CHECK_KEY("F18", VK_F18)
    CHECK_KEY("F19", VK_F19)
    CHECK_KEY("F20", VK_F20)
    CHECK_KEY("F21", VK_F21)
    CHECK_KEY("F22", VK_F22)
    CHECK_KEY("F23", VK_F23)
    CHECK_KEY("F24", VK_F24)
    CHECK_KEY("NUMLOCK", VK_NUMLOCK)
    CHECK_KEY("SCROLLLOCK", VK_SCROLL)

    return false;
}

void AssignHotkey(int* inoutArgIdx, int argc, char** argv, CommandLineArgs* args)
{
    auto argIdx = *inoutArgIdx;

    args->mHotkeySupport = true;
    if (++argIdx == argc) {
        return;
    }

#pragma warning(suppress: 4996)
    auto token = strtok(argv[argIdx], "+");
    for (;;) {
        auto prev = token;
#pragma warning(suppress: 4996)
        token = strtok(nullptr, "+");
        if (token == nullptr) {
            if (!ParseKeyCode(prev, &args->mHotkeyVirtualKeyCode)) {
                return;
            }
            break;
        }

        if (!ParseModifier(prev, &args->mHotkeyModifiers)) {
            return;
        }
    }

    *inoutArgIdx = argIdx;
}

UINT atou(char const* a)
{
    int i = atoi(a);
    return i <= 0 ? 0 : (UINT) i;
}

void PrintHelp()
{
    // NOTE: remember to update README.md when modifying usage
    fprintf(stderr,
        "PresentMon version 1.1.2\n"
        "\n"
        "Capture target options:\n"
        "    -captureall                Record all processes (default).\n"
        "    -process_name [exe name]   Record specific process specified by name.\n"
        "    -process_id [integer]      Record specific process specified by ID.\n"
        "\n"
        "Output options:\n"
        "    -no_csv                    Do not create any output file.\n"
        "    -output_file [path]        Write CSV output to specified path. Otherwise, the default is\n"
        "                               PresentMon-PROCESSNAME-TIME.csv.\n"
        "\n"
        "Control and filtering options:\n"
        "    -etl_file [path]           Consume events from an ETL file instead of a running process.\n"
        "    -scroll_toggle             Only record events while scroll lock is enabled.\n"
        "    -scroll_indicator          Set scroll lock while recording events.\n"
        "    -hotkey [key]              Use specified key to start and stop recording, writing to a\n"
        "                               unique file each time (default is F11).\n"
        "    -delay [seconds]           Wait for specified time before starting to record. When using\n"
        "                               -hotkey, delay occurs each time recording is started.\n"
        "    -timed [seconds]           Stop recording after the specified amount of time.  PresentMon will exit\n"
        "                               timer expires.\n"
        "    -exclude_dropped           Exclude dropped presents from the csv output.\n"
        "    -terminate_on_proc_exit    Terminate PresentMon when all instances of the specified process exit.\n"
        "    -terminate_after_timed     Terminate PresentMon after the timed trace, specified using -timed, completes.\n"
        "    -simple                    Disable advanced tracking (try this if you encounter crashes).\n"
        "    -dont_restart_as_admin     Don't try to elevate privilege.\n"
        "    -no_top                    Don't display active swap chains in the console window.\n"
        );
}

}

bool ParseCommandLine(int argc, char** argv, CommandLineArgs* args)
{
    for (int i = 1; i < argc; ++i) {
#define ARG1(Arg, Assign) \
        if (strcmp(argv[i], Arg) == 0) { \
            Assign; \
            continue; \
        }

#define ARG2(Arg, Assign) \
        if (strcmp(argv[i], Arg) == 0) { \
            if (++i < argc) { \
                Assign; \
                continue; \
            } \
            fprintf(stderr, "error: %s expecting argument.\n", Arg); \
        }

        // Capture target options
             ARG1("-captureall",             args->mTargetProcessName   = nullptr)
        else ARG2("-process_name",           args->mTargetProcessName   = argv[i])
        else ARG2("-process_id",             args->mTargetPid           = atou(argv[i]))
        else ARG2("-etl_file",               args->mEtlFileName         = argv[i])

        // Output options
        else ARG1("-no_csv",                 args->mOutputFile          = false)
        else ARG2("-output_file",            args->mOutputFileName      = argv[i])

        // Control and filtering options
        else ARG1("-hotkey",                 AssignHotkey(&i, argc, argv, args))
        else ARG1("-scroll_toggle",          args->mScrollLockToggle    = true)
        else ARG1("-scroll_indicator",       args->mScrollLockIndicator = true)
        else ARG2("-delay",                  args->mDelay               = atou(argv[i]))
        else ARG2("-timed",                  args->mTimer               = atou(argv[i]))
        else ARG1("-exclude_dropped",        args->mExcludeDropped      = true)
        else ARG1("-terminate_on_proc_exit", args->mTerminateOnProcExit = true)
        else ARG1("-terminate_after_timed",  args->mTerminateAfterTimer = true)
        else ARG1("-simple",                 args->mSimple              = true)
        else ARG1("-dont_restart_as_admin",  args->mTryToElevate        = false)
        else ARG1("-no_top",                 args->mSimpleConsole       = true)

        // Provided argument wasn't recognized
        else fprintf(stderr, "error: %s '%s'.\n",
            i > 0 && strcmp(argv[i - 1], "-hotkey") == 0 ? "failed to parse hotkey" : "unrecognized argument",
            argv[i]);

        PrintHelp();
        return false;
    }

    // Validate command line arguments
    if (((args->mTargetProcessName == nullptr) ? 0 : 1) +
        ((args->mTargetPid         <= 0      ) ? 0 : 1) > 1) {
        fprintf(stderr, "error: only specify one of -captureall, -process_name, or -process_id.\n");
        PrintHelp();
        return false;
    }

    if (args->mEtlFileName && args->mHotkeySupport) {
        fprintf(stderr, "error: -etl_file and -hotkey arguments are not compatible.\n");
        PrintHelp();
        return false;
    }

    if (args->mHotkeySupport) {
        if ((args->mHotkeyModifiers & MOD_CONTROL) != 0 && args->mHotkeyVirtualKeyCode == 0x44 /*C*/) {
            fprintf(stderr, "error: 'CTRL+C' cannot be used as a -hotkey, it is reserved for terminating the trace.\n");
            PrintHelp();
            return false;
        }

        if (args->mHotkeyModifiers == MOD_NOREPEAT && args->mHotkeyVirtualKeyCode == VK_F12) {
            fprintf(stderr, "error: 'F12' cannot be used as a -hotkey, it is reserved for the debugger.\n");
            PrintHelp();
            return false;
        }
    }

    return true;
}

bool RestartAsAdministrator(
    int argc,
    char** argv)
{
    char exe_path[MAX_PATH] = {};
    GetModuleFileNameA(NULL, exe_path, sizeof(exe_path));

    char args[MAX_PATH] = {};
    if (!CombineArguments(argc, argv, args, MAX_PATH)) {
        return false;
    }

    ShellExecuteA(NULL, "runas", exe_path, args, NULL, SW_SHOW);
    return true;
}

void SetConsoleTitle(
    int argc,
    char** argv)
{
    char args[MAX_PATH] = {};
    size_t idx = snprintf(args, MAX_PATH, "PresentMon");
    if (!CombineArguments(argc, argv, args + idx, MAX_PATH - idx)) {
        args[MAX_PATH - 4] = '.';
        args[MAX_PATH - 3] = '.';
        args[MAX_PATH - 2] = '.';
    }

    SetConsoleTitleA(args);
}

bool EnableScrollLock(bool enable)
{
    auto enabled = (GetKeyState(VK_SCROLL) & 1) == 1;
    if (enabled != enable) {
        auto extraInfo = GetMessageExtraInfo();
        INPUT input[2] = {};

        input[0].type = INPUT_KEYBOARD;
        input[0].ki.wVk = VK_SCROLL;
        input[0].ki.dwExtraInfo = extraInfo;

        input[1].type = INPUT_KEYBOARD;
        input[1].ki.wVk = VK_SCROLL;
        input[1].ki.dwFlags = KEYEVENTF_KEYUP;
        input[1].ki.dwExtraInfo = extraInfo;

        auto sendCount = SendInput(2, input, sizeof(INPUT));
        if (sendCount != 2) {
            fprintf(stderr, "warning: could not toggle scroll lock.\n");
        }
    }

    return enabled;
}

<|endoftext|>


<commit_before>#include "DrawTexture.h"
#include "DTEX_Texture.h"
#include "DTEX_Math.h"
#include "RenderAPI.h"
#include "ResCache.h"
#include "Target.h"

namespace dtex
{

SINGLETON_DEFINITION(DrawTexture);

DrawTexture::DrawTexture()
	: m_curr(NULL)
{
}

void DrawTexture::Draw(int src_tex_id, int src_w, int src_h, const Rect& src_r, Texture* dst, const Rect& dst_r, bool rotate)
{
	Bind(dst);

	float vertices[8];
	float w_inv = m_curr->GetWidthInv(),
		  h_inv = m_curr->GetHeightInv();
	float dst_xmin = dst_r.xmin * w_inv * 2 - 1,
		  dst_xmax = dst_r.xmax * w_inv * 2 - 1,
		  dst_ymin = dst_r.ymin * h_inv * 2 - 1,
		  dst_ymax = dst_r.ymax * h_inv * 2 - 1;
	vertices[0] = dst_xmin; vertices[1] = dst_ymin;
	vertices[2] = dst_xmax; vertices[3] = dst_ymin;
	vertices[4] = dst_xmax; vertices[5] = dst_ymax;
	vertices[6] = dst_xmin; vertices[7] = dst_ymax;
	if (rotate)
	{
		float x, y;
		x = vertices[6]; y = vertices[7];
		vertices[6] = vertices[4]; vertices[7] = vertices[5];
		vertices[4] = vertices[2]; vertices[5] = vertices[3];
		vertices[2] = vertices[0]; vertices[3] = vertices[1];
		vertices[0] = x;           vertices[1] = y;
	}

	float texcoords[8];
	float src_w_inv = 1.0f / src_w,
		  src_h_inv = 1.0f / src_h;
	float src_xmin = src_r.xmin * src_w_inv,
		  src_xmax = src_r.xmax * src_w_inv,
		  src_ymin = src_r.ymin * src_h_inv,
		  src_ymax = src_r.ymax * src_h_inv;
	texcoords[0] = src_xmin; texcoords[1] = src_ymin;
	texcoords[2] = src_xmax; texcoords[3] = src_ymin;
	texcoords[4] = src_xmax; texcoords[5] = src_ymax;
	texcoords[6] = src_xmin; texcoords[7] = src_ymax;

	RenderAPI::SetProgram();
	RenderAPI::Draw(vertices, texcoords, src_tex_id);
}

void DrawTexture::ClearTex(Texture* tex)
{
	Target* target = ResCache::Instance()->FetchTarget();

	target->Bind();
	target->BindTexture(tex->GetID());

	RenderAPI::ClearColor(0, 0, 0, 0);

	target->UnbindTexture();
	target->Unbind();

	ResCache::Instance()->ReturnTarget(target);
}

void DrawTexture::ClearTex(Texture* tex, float xmin, float ymin, float xmax, float ymax)
{
	Bind(tex);

	int w = m_curr->GetWidth(),
		h = m_curr->GetHeight();
	RenderAPI::ScissorPush(
		w * xmin,
		h * ymin,
		w * (xmax - xmin),
		h * (ymax - ymin));
	RenderAPI::ClearColor(0, 0, 0, 0);
	RenderAPI::ScissorPop();
}

void DrawTexture::Flush()
{
	if (m_curr) {
		DrawAfter(m_ctx);
		m_curr = NULL;
	}
}

void DrawTexture::Clear()
{
	m_curr = NULL;

	if (m_ctx.target) {
		ResCache::Instance()->ReturnTarget(m_ctx.target);
		m_ctx.target = NULL;
	}
}

void DrawTexture::DrawBefore(Context& ctx)
{
	RenderAPI::DrawBegin();
	RenderAPI::GetViewport(ctx.vx, ctx.vy, ctx.vw, ctx.vh);
	RenderAPI::SetViewport(0, 0, m_curr->GetWidth(), m_curr->GetHeight());

	Target* target = ResCache::Instance()->FetchTarget();
	target->Bind();
	target->BindTexture(m_curr->GetID());

	ctx.target = target;
}

void DrawTexture::DrawAfter(Context& ctx)
{
	ctx.target->UnbindTexture();
	ctx.target->Unbind();
	ResCache::Instance()->ReturnTarget(ctx.target);
	ctx.target = NULL;

	RenderAPI::SetViewport(ctx.vx, ctx.vy, ctx.vw, ctx.vh);
	RenderAPI::DrawEnd();
}

void DrawTexture::Bind(Texture* tex)
{
	if (!tex || m_curr == tex) {
		return;
	}
	if (m_curr) {
		DrawAfter(m_ctx);
	}
	m_curr = tex;
	DrawBefore(m_ctx);
}

}<commit_msg>[FIXED] clear all tex<commit_after>#include "DrawTexture.h"
#include "DTEX_Texture.h"
#include "DTEX_Math.h"
#include "RenderAPI.h"
#include "ResCache.h"
#include "Target.h"

namespace dtex
{

SINGLETON_DEFINITION(DrawTexture);

DrawTexture::DrawTexture()
	: m_curr(NULL)
{
}

void DrawTexture::Draw(int src_tex_id, int src_w, int src_h, const Rect& src_r, Texture* dst, const Rect& dst_r, bool rotate)
{
	Bind(dst);

	float vertices[8];
	float w_inv = m_curr->GetWidthInv(),
		  h_inv = m_curr->GetHeightInv();
	float dst_xmin = dst_r.xmin * w_inv * 2 - 1,
		  dst_xmax = dst_r.xmax * w_inv * 2 - 1,
		  dst_ymin = dst_r.ymin * h_inv * 2 - 1,
		  dst_ymax = dst_r.ymax * h_inv * 2 - 1;
	vertices[0] = dst_xmin; vertices[1] = dst_ymin;
	vertices[2] = dst_xmax; vertices[3] = dst_ymin;
	vertices[4] = dst_xmax; vertices[5] = dst_ymax;
	vertices[6] = dst_xmin; vertices[7] = dst_ymax;
	if (rotate)
	{
		float x, y;
		x = vertices[6]; y = vertices[7];
		vertices[6] = vertices[4]; vertices[7] = vertices[5];
		vertices[4] = vertices[2]; vertices[5] = vertices[3];
		vertices[2] = vertices[0]; vertices[3] = vertices[1];
		vertices[0] = x;           vertices[1] = y;
	}

	float texcoords[8];
	float src_w_inv = 1.0f / src_w,
		  src_h_inv = 1.0f / src_h;
	float src_xmin = src_r.xmin * src_w_inv,
		  src_xmax = src_r.xmax * src_w_inv,
		  src_ymin = src_r.ymin * src_h_inv,
		  src_ymax = src_r.ymax * src_h_inv;
	texcoords[0] = src_xmin; texcoords[1] = src_ymin;
	texcoords[2] = src_xmax; texcoords[3] = src_ymin;
	texcoords[4] = src_xmax; texcoords[5] = src_ymax;
	texcoords[6] = src_xmin; texcoords[7] = src_ymax;

	RenderAPI::SetProgram();
	RenderAPI::Draw(vertices, texcoords, src_tex_id);
}

void DrawTexture::ClearTex(Texture* tex)
{
	Bind(tex);
	RenderAPI::ClearColor(0, 0, 0, 0);
}

void DrawTexture::ClearTex(Texture* tex, float xmin, float ymin, float xmax, float ymax)
{
	Bind(tex);

	int w = m_curr->GetWidth(),
		h = m_curr->GetHeight();
	RenderAPI::ScissorPush(
		w * xmin,
		h * ymin,
		w * (xmax - xmin),
		h * (ymax - ymin));
	RenderAPI::ClearColor(0, 0, 0, 0);
	RenderAPI::ScissorPop();
}

void DrawTexture::Flush()
{
	if (m_curr) {
		DrawAfter(m_ctx);
		m_curr = NULL;
	}
}

void DrawTexture::Clear()
{
	m_curr = NULL;

	if (m_ctx.target) {
		ResCache::Instance()->ReturnTarget(m_ctx.target);
		m_ctx.target = NULL;
	}
}

void DrawTexture::DrawBefore(Context& ctx)
{
	RenderAPI::DrawBegin();
	RenderAPI::GetViewport(ctx.vx, ctx.vy, ctx.vw, ctx.vh);
	RenderAPI::SetViewport(0, 0, m_curr->GetWidth(), m_curr->GetHeight());

	Target* target = ResCache::Instance()->FetchTarget();
	target->Bind();
	target->BindTexture(m_curr->GetID());

	ctx.target = target;
}

void DrawTexture::DrawAfter(Context& ctx)
{
	ctx.target->UnbindTexture();
	ctx.target->Unbind();
	ResCache::Instance()->ReturnTarget(ctx.target);
	ctx.target = NULL;

	RenderAPI::SetViewport(ctx.vx, ctx.vy, ctx.vw, ctx.vh);
	RenderAPI::DrawEnd();
}

void DrawTexture::Bind(Texture* tex)
{
	if (!tex || m_curr == tex) {
		return;
	}
	if (m_curr) {
		DrawAfter(m_ctx);
	}
	m_curr = tex;
	DrawBefore(m_ctx);
}

}<|endoftext|>