<commit_before>/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrVkCaps.h"
#include "GrRenderTargetProxy.h"
#include "GrShaderCaps.h"
#include "GrVkUtil.h"
#include "vk/GrVkBackendContext.h"
#include "vk/GrVkInterface.h"

GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
                   VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags)
    : INHERITED(contextOptions) {
    fCanUseGLSLForShaderModule = false;
    fMustDoCopiesFromOrigin = false;
    fSupportsCopiesAsDraws = false;
    fMustSubmitCommandsBeforeCopyOp = false;
    fMustSleepOnTearDown  = false;
    fNewSecondaryCBOnPipelineChange = false;

    /**************************************************************************
    * GrDrawTargetCaps fields
    **************************************************************************/
    fMipMapSupport = true;   // always available in Vulkan
    fSRGBSupport = true;   // always available in Vulkan
    fNPOTTextureTileSupport = true;  // always available in Vulkan
    fDiscardRenderTargetSupport = true;
    fReuseScratchTextures = true; //TODO: figure this out
    fGpuTracingSupport = false; //TODO: figure this out
    fCompressedTexSubImageSupport = false; //TODO: figure this out
    fOversizedStencilSupport = false; //TODO: figure this out

    fUseDrawInsteadOfClear = false;
    fFenceSyncSupport = true;   // always available in Vulkan
    fCrossContextTextureSupport = true;

    fMapBufferFlags = kNone_MapFlags; //TODO: figure this out
    fBufferMapThreshold = SK_MaxS32;  //TODO: figure this out

    fMaxRenderTargetSize = 4096; // minimum required by spec
    fMaxTextureSize = 4096; // minimum required by spec
    fMaxColorSampleCount = 4; // minimum required by spec
    fMaxStencilSampleCount = 4; // minimum required by spec

    fShaderCaps.reset(new GrShaderCaps(contextOptions));

    this->init(contextOptions, vkInterface, physDev, featureFlags, extensionFlags);
}

bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
                                  bool* rectsMustMatch, bool* disallowSubrect) const {
    // Vk doesn't use rectsMustMatch or disallowSubrect. Always return false.
    *rectsMustMatch = false;
    *disallowSubrect = false;

    // We can always succeed here with either a CopyImage (none msaa src) or ResolveImage (msaa).
    // For CopyImage we can make a simple texture, for ResolveImage we require the dst to be a
    // render target as well.
    desc->fOrigin = src->origin();
    desc->fConfig = src->config();
    if (src->numColorSamples() > 1 || (src->asTextureProxy() && this->supportsCopiesAsDraws())) {
        desc->fFlags = kRenderTarget_GrSurfaceFlag;
    } else {
        // Just going to use CopyImage here
        desc->fFlags = kNone_GrSurfaceFlags;
    }

    return true;
}

void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
                    VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags) {

    VkPhysicalDeviceProperties properties;
    GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));

    VkPhysicalDeviceMemoryProperties memoryProperties;
    GR_VK_CALL(vkInterface, GetPhysicalDeviceMemoryProperties(physDev, &memoryProperties));

    this->initGrCaps(properties, memoryProperties, featureFlags);
    this->initShaderCaps(properties, featureFlags);
    this->initConfigTable(vkInterface, physDev);
    this->initStencilFormat(vkInterface, physDev);

    if (SkToBool(extensionFlags & kNV_glsl_shader_GrVkExtensionFlag)) {
        // Currently disabling this feature since it does not play well with validation layers which
        // expect a SPIR-V shader
        // fCanUseGLSLForShaderModule = true;
    }

    if (kQualcomm_VkVendor == properties.vendorID) {
        fMustDoCopiesFromOrigin = true;
    }

    if (kNvidia_VkVendor == properties.vendorID) {
        fSupportsCopiesAsDraws = true;
        fMustSubmitCommandsBeforeCopyOp = true;
    }

#if defined(SK_BUILD_FOR_WIN)
    if (kNvidia_VkVendor == properties.vendorID) {
        fMustSleepOnTearDown = true;
    }
#elif defined(SK_BUILD_FOR_ANDROID)
    if (kImagination_VkVendor == properties.vendorID) {
        fMustSleepOnTearDown = true;
    }
#endif

    this->applyOptionsOverrides(contextOptions);
    fShaderCaps->applyOptionsOverrides(contextOptions);
}

int get_max_sample_count(VkSampleCountFlags flags) {
    SkASSERT(flags & VK_SAMPLE_COUNT_1_BIT);
    if (!(flags & VK_SAMPLE_COUNT_2_BIT)) {
        return 0;
    }
    if (!(flags & VK_SAMPLE_COUNT_4_BIT)) {
        return 2;
    }
    if (!(flags & VK_SAMPLE_COUNT_8_BIT)) {
        return 4;
    }
    if (!(flags & VK_SAMPLE_COUNT_16_BIT)) {
        return 8;
    }
    if (!(flags & VK_SAMPLE_COUNT_32_BIT)) {
        return 16;
    }
    if (!(flags & VK_SAMPLE_COUNT_64_BIT)) {
        return 32;
    }
    return 64;
}

void GrVkCaps::initSampleCount(const VkPhysicalDeviceProperties& properties) {
    VkSampleCountFlags colorSamples = properties.limits.framebufferColorSampleCounts;
    VkSampleCountFlags stencilSamples = properties.limits.framebufferStencilSampleCounts;

    fMaxColorSampleCount = get_max_sample_count(colorSamples);
    if (kImagination_VkVendor == properties.vendorID) {
        fMaxColorSampleCount = 0;
    }
    fMaxStencilSampleCount = get_max_sample_count(stencilSamples);
}

void GrVkCaps::initGrCaps(const VkPhysicalDeviceProperties& properties,
                          const VkPhysicalDeviceMemoryProperties& memoryProperties,
                          uint32_t featureFlags) {
    // So GPUs, like AMD, are reporting MAX_INT support vertex attributes. In general, there is no
    // need for us ever to support that amount, and it makes tests which tests all the vertex
    // attribs timeout looping over that many. For now, we'll cap this at 64 max and can raise it if
    // we ever find that need.
    static const uint32_t kMaxVertexAttributes = 64;
    fMaxVertexAttributes = SkTMin(properties.limits.maxVertexInputAttributes, kMaxVertexAttributes);
    // AMD advertises support for MAX_UINT vertex input attributes, but in reality only supports 32.
    if (kAMD_VkVendor == properties.vendorID) {
        fMaxVertexAttributes = SkTMin(fMaxVertexAttributes, 32);
    }

    // We could actually query and get a max size for each config, however maxImageDimension2D will
    // give the minimum max size across all configs. So for simplicity we will use that for now.
    fMaxRenderTargetSize = SkTMin(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);
    fMaxTextureSize = SkTMin(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);

    this->initSampleCount(properties);

    // Assuming since we will always map in the end to upload the data we might as well just map
    // from the get go. There is no hard data to suggest this is faster or slower.
    fBufferMapThreshold = 0;

    fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;

    fOversizedStencilSupport = true;
    fSampleShadingSupport = SkToBool(featureFlags & kSampleRateShading_GrVkFeatureFlag);

    // AMD seems to have issues binding new VkPipelines inside a secondary command buffer.
    // Current workaround is to use a different secondary command buffer for each new VkPipeline.
    if (kAMD_VkVendor == properties.vendorID) {
        fNewSecondaryCBOnPipelineChange = true;
    }
}

void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties, uint32_t featureFlags) {
    GrShaderCaps* shaderCaps = fShaderCaps.get();
    shaderCaps->fVersionDeclString = "#version 330\n";

    // fConfigOutputSwizzle will default to RGBA so we only need to set it for alpha only config.
    for (int i = 0; i < kGrPixelConfigCnt; ++i) {
        GrPixelConfig config = static_cast<GrPixelConfig>(i);
        if (GrPixelConfigIsAlphaOnly(config)) {
            shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRR();
            shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
        } else {
            if (kGray_8_GrPixelConfig == config) {
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRA();
            } else if (kRGBA_4444_GrPixelConfig == config) {
                // The vulkan spec does not require R4G4B4A4 to be supported for texturing so we
                // store the data in a B4G4R4A4 texture and then swizzle it when doing texture reads
                // or writing to outputs. Since we're not actually changing the data at all, the
                // only extra work is the swizzle in the shader for all operations.
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::BGRA();
                shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::BGRA();
            } else {
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGBA();
            }
        }
    }

    if (kImagination_VkVendor == properties.vendorID) {
        shaderCaps->fAtan2ImplementedAsAtanYOverX = true;
    }

    // Vulkan is based off ES 3.0 so the following should all be supported
    shaderCaps->fUsesPrecisionModifiers = true;
    shaderCaps->fFlatInterpolationSupport = true;

    // GrShaderCaps

    shaderCaps->fShaderDerivativeSupport = true;
    shaderCaps->fGeometryShaderSupport = SkToBool(featureFlags & kGeometryShader_GrVkFeatureFlag);

    shaderCaps->fDualSourceBlendingSupport = SkToBool(featureFlags & kDualSrcBlend_GrVkFeatureFlag);
    if (kAMD_VkVendor == properties.vendorID) {
        // Currently DualSourceBlending is not working on AMD. vkCreateGraphicsPipeline fails when
        // using a draw with dual source. Looking into whether it is driver bug or issue with our
        // SPIR-V. Bug skia:6405
        shaderCaps->fDualSourceBlendingSupport = false;
    }

    shaderCaps->fIntegerSupport = true;

    // Assume the minimum precisions mandated by the SPIR-V spec.
    shaderCaps->fShaderPrecisionVaries = true;
    for (int s = 0; s < kGrShaderTypeCount; ++s) {
        auto& highp = shaderCaps->fFloatPrecisions[s][kHigh_GrSLPrecision];
        highp.fLogRangeLow = highp.fLogRangeHigh = 127;
        highp.fBits = 23;

        auto& mediump = shaderCaps->fFloatPrecisions[s][kMedium_GrSLPrecision];
        mediump.fLogRangeLow = mediump.fLogRangeHigh = 14;
        mediump.fBits = 10;

        shaderCaps->fFloatPrecisions[s][kLow_GrSLPrecision] = mediump;
    }
    shaderCaps->initSamplerPrecisionTable();

    shaderCaps->fMaxVertexSamplers =
    shaderCaps->fMaxGeometrySamplers =
    shaderCaps->fMaxFragmentSamplers = SkTMin(
                                       SkTMin(properties.limits.maxPerStageDescriptorSampledImages,
                                              properties.limits.maxPerStageDescriptorSamplers),
                                              (uint32_t)INT_MAX);
    shaderCaps->fMaxCombinedSamplers = SkTMin(
                                       SkTMin(properties.limits.maxDescriptorSetSampledImages,
                                              properties.limits.maxDescriptorSetSamplers),
                                              (uint32_t)INT_MAX);
}

bool stencil_format_supported(const GrVkInterface* interface,
                              VkPhysicalDevice physDev,
                              VkFormat format) {
    VkFormatProperties props;
    memset(&props, 0, sizeof(VkFormatProperties));
    GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
    return SkToBool(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT & props.optimalTilingFeatures);
}

void GrVkCaps::initStencilFormat(const GrVkInterface* interface, VkPhysicalDevice physDev) {
    // List of legal stencil formats (though perhaps not supported on
    // the particular gpu/driver) from most preferred to least. We are guaranteed to have either
    // VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT. VK_FORMAT_D32_SFLOAT_S8_UINT
    // can optionally have 24 unused bits at the end so we assume the total bits is 64.
    static const StencilFormat
                  // internal Format             stencil bits      total bits        packed?
        gS8    = { VK_FORMAT_S8_UINT,            8,                 8,               false },
        gD24S8 = { VK_FORMAT_D24_UNORM_S8_UINT,  8,                32,               true },
        gD32S8 = { VK_FORMAT_D32_SFLOAT_S8_UINT, 8,                64,               true };

    if (stencil_format_supported(interface, physDev, VK_FORMAT_S8_UINT)) {
        fPreferedStencilFormat = gS8;
    } else if (stencil_format_supported(interface, physDev, VK_FORMAT_D24_UNORM_S8_UINT)) {
        fPreferedStencilFormat = gD24S8;
    } else {
        SkASSERT(stencil_format_supported(interface, physDev, VK_FORMAT_D32_SFLOAT_S8_UINT));
        fPreferedStencilFormat = gD32S8;
    }
}

void GrVkCaps::initConfigTable(const GrVkInterface* interface, VkPhysicalDevice physDev) {
    for (int i = 0; i < kGrPixelConfigCnt; ++i) {
        VkFormat format;
        if (GrPixelConfigToVkFormat(static_cast<GrPixelConfig>(i), &format)) {
            fConfigTable[i].init(interface, physDev, format);
        }
    }

    // We currently do not support compressed textures in Vulkan
    const uint16_t kFlagsToRemove = ConfigInfo::kTextureable_Flag|ConfigInfo::kRenderable_Flag;
    fConfigTable[kETC1_GrPixelConfig].fOptimalFlags &= ~kFlagsToRemove;
    fConfigTable[kETC1_GrPixelConfig].fLinearFlags &= ~kFlagsToRemove;
}

void GrVkCaps::ConfigInfo::InitConfigFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags) {
    if (SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & vkFlags) &&
        SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT & vkFlags)) {
        *flags = *flags | kTextureable_Flag;
    }

    if (SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT & vkFlags)) {
        *flags = *flags | kRenderable_Flag;
    }

    if (SkToBool(VK_FORMAT_FEATURE_BLIT_SRC_BIT & vkFlags)) {
        *flags = *flags | kBlitSrc_Flag;
    }

    if (SkToBool(VK_FORMAT_FEATURE_BLIT_DST_BIT & vkFlags)) {
        *flags = *flags | kBlitDst_Flag;
    }
}

void GrVkCaps::ConfigInfo::init(const GrVkInterface* interface,
                                VkPhysicalDevice physDev,
                                VkFormat format) {
    VkFormatProperties props;
    memset(&props, 0, sizeof(VkFormatProperties));
    GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
    InitConfigFlags(props.linearTilingFeatures, &fLinearFlags);
    InitConfigFlags(props.optimalTilingFeatures, &fOptimalFlags);
}
<commit_msg>Require copy as draws for vulkan cross context image support<commit_after>/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrVkCaps.h"
#include "GrRenderTargetProxy.h"
#include "GrShaderCaps.h"
#include "GrVkUtil.h"
#include "vk/GrVkBackendContext.h"
#include "vk/GrVkInterface.h"

GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
                   VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags)
    : INHERITED(contextOptions) {
    fCanUseGLSLForShaderModule = false;
    fMustDoCopiesFromOrigin = false;
    fSupportsCopiesAsDraws = false;
    fMustSubmitCommandsBeforeCopyOp = false;
    fMustSleepOnTearDown  = false;
    fNewSecondaryCBOnPipelineChange = false;

    /**************************************************************************
    * GrDrawTargetCaps fields
    **************************************************************************/
    fMipMapSupport = true;   // always available in Vulkan
    fSRGBSupport = true;   // always available in Vulkan
    fNPOTTextureTileSupport = true;  // always available in Vulkan
    fDiscardRenderTargetSupport = true;
    fReuseScratchTextures = true; //TODO: figure this out
    fGpuTracingSupport = false; //TODO: figure this out
    fCompressedTexSubImageSupport = false; //TODO: figure this out
    fOversizedStencilSupport = false; //TODO: figure this out

    fUseDrawInsteadOfClear = false;
    fFenceSyncSupport = true;   // always available in Vulkan
    fCrossContextTextureSupport = false;

    fMapBufferFlags = kNone_MapFlags; //TODO: figure this out
    fBufferMapThreshold = SK_MaxS32;  //TODO: figure this out

    fMaxRenderTargetSize = 4096; // minimum required by spec
    fMaxTextureSize = 4096; // minimum required by spec
    fMaxColorSampleCount = 4; // minimum required by spec
    fMaxStencilSampleCount = 4; // minimum required by spec

    fShaderCaps.reset(new GrShaderCaps(contextOptions));

    this->init(contextOptions, vkInterface, physDev, featureFlags, extensionFlags);
}

bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
                                  bool* rectsMustMatch, bool* disallowSubrect) const {
    // Vk doesn't use rectsMustMatch or disallowSubrect. Always return false.
    *rectsMustMatch = false;
    *disallowSubrect = false;

    // We can always succeed here with either a CopyImage (none msaa src) or ResolveImage (msaa).
    // For CopyImage we can make a simple texture, for ResolveImage we require the dst to be a
    // render target as well.
    desc->fOrigin = src->origin();
    desc->fConfig = src->config();
    if (src->numColorSamples() > 1 || (src->asTextureProxy() && this->supportsCopiesAsDraws())) {
        desc->fFlags = kRenderTarget_GrSurfaceFlag;
    } else {
        // Just going to use CopyImage here
        desc->fFlags = kNone_GrSurfaceFlags;
    }

    return true;
}

void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
                    VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags) {

    VkPhysicalDeviceProperties properties;
    GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));

    VkPhysicalDeviceMemoryProperties memoryProperties;
    GR_VK_CALL(vkInterface, GetPhysicalDeviceMemoryProperties(physDev, &memoryProperties));

    this->initGrCaps(properties, memoryProperties, featureFlags);
    this->initShaderCaps(properties, featureFlags);
    this->initConfigTable(vkInterface, physDev);
    this->initStencilFormat(vkInterface, physDev);

    if (SkToBool(extensionFlags & kNV_glsl_shader_GrVkExtensionFlag)) {
        // Currently disabling this feature since it does not play well with validation layers which
        // expect a SPIR-V shader
        // fCanUseGLSLForShaderModule = true;
    }

    if (kQualcomm_VkVendor == properties.vendorID) {
        fMustDoCopiesFromOrigin = true;
    }

    if (kNvidia_VkVendor == properties.vendorID) {
        fSupportsCopiesAsDraws = true;
        fMustSubmitCommandsBeforeCopyOp = true;
    }

    if (fSupportsCopiesAsDraws) {
        fCrossContextTextureSupport = true;
    }

#if defined(SK_BUILD_FOR_WIN)
    if (kNvidia_VkVendor == properties.vendorID) {
        fMustSleepOnTearDown = true;
    }
#elif defined(SK_BUILD_FOR_ANDROID)
    if (kImagination_VkVendor == properties.vendorID) {
        fMustSleepOnTearDown = true;
    }
#endif

    this->applyOptionsOverrides(contextOptions);
    fShaderCaps->applyOptionsOverrides(contextOptions);
}

int get_max_sample_count(VkSampleCountFlags flags) {
    SkASSERT(flags & VK_SAMPLE_COUNT_1_BIT);
    if (!(flags & VK_SAMPLE_COUNT_2_BIT)) {
        return 0;
    }
    if (!(flags & VK_SAMPLE_COUNT_4_BIT)) {
        return 2;
    }
    if (!(flags & VK_SAMPLE_COUNT_8_BIT)) {
        return 4;
    }
    if (!(flags & VK_SAMPLE_COUNT_16_BIT)) {
        return 8;
    }
    if (!(flags & VK_SAMPLE_COUNT_32_BIT)) {
        return 16;
    }
    if (!(flags & VK_SAMPLE_COUNT_64_BIT)) {
        return 32;
    }
    return 64;
}

void GrVkCaps::initSampleCount(const VkPhysicalDeviceProperties& properties) {
    VkSampleCountFlags colorSamples = properties.limits.framebufferColorSampleCounts;
    VkSampleCountFlags stencilSamples = properties.limits.framebufferStencilSampleCounts;

    fMaxColorSampleCount = get_max_sample_count(colorSamples);
    if (kImagination_VkVendor == properties.vendorID) {
        fMaxColorSampleCount = 0;
    }
    fMaxStencilSampleCount = get_max_sample_count(stencilSamples);
}

void GrVkCaps::initGrCaps(const VkPhysicalDeviceProperties& properties,
                          const VkPhysicalDeviceMemoryProperties& memoryProperties,
                          uint32_t featureFlags) {
    // So GPUs, like AMD, are reporting MAX_INT support vertex attributes. In general, there is no
    // need for us ever to support that amount, and it makes tests which tests all the vertex
    // attribs timeout looping over that many. For now, we'll cap this at 64 max and can raise it if
    // we ever find that need.
    static const uint32_t kMaxVertexAttributes = 64;
    fMaxVertexAttributes = SkTMin(properties.limits.maxVertexInputAttributes, kMaxVertexAttributes);
    // AMD advertises support for MAX_UINT vertex input attributes, but in reality only supports 32.
    if (kAMD_VkVendor == properties.vendorID) {
        fMaxVertexAttributes = SkTMin(fMaxVertexAttributes, 32);
    }

    // We could actually query and get a max size for each config, however maxImageDimension2D will
    // give the minimum max size across all configs. So for simplicity we will use that for now.
    fMaxRenderTargetSize = SkTMin(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);
    fMaxTextureSize = SkTMin(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);

    this->initSampleCount(properties);

    // Assuming since we will always map in the end to upload the data we might as well just map
    // from the get go. There is no hard data to suggest this is faster or slower.
    fBufferMapThreshold = 0;

    fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;

    fOversizedStencilSupport = true;
    fSampleShadingSupport = SkToBool(featureFlags & kSampleRateShading_GrVkFeatureFlag);

    // AMD seems to have issues binding new VkPipelines inside a secondary command buffer.
    // Current workaround is to use a different secondary command buffer for each new VkPipeline.
    if (kAMD_VkVendor == properties.vendorID) {
        fNewSecondaryCBOnPipelineChange = true;
    }
}

void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties, uint32_t featureFlags) {
    GrShaderCaps* shaderCaps = fShaderCaps.get();
    shaderCaps->fVersionDeclString = "#version 330\n";

    // fConfigOutputSwizzle will default to RGBA so we only need to set it for alpha only config.
    for (int i = 0; i < kGrPixelConfigCnt; ++i) {
        GrPixelConfig config = static_cast<GrPixelConfig>(i);
        if (GrPixelConfigIsAlphaOnly(config)) {
            shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRR();
            shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
        } else {
            if (kGray_8_GrPixelConfig == config) {
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRA();
            } else if (kRGBA_4444_GrPixelConfig == config) {
                // The vulkan spec does not require R4G4B4A4 to be supported for texturing so we
                // store the data in a B4G4R4A4 texture and then swizzle it when doing texture reads
                // or writing to outputs. Since we're not actually changing the data at all, the
                // only extra work is the swizzle in the shader for all operations.
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::BGRA();
                shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::BGRA();
            } else {
                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGBA();
            }
        }
    }

    if (kImagination_VkVendor == properties.vendorID) {
        shaderCaps->fAtan2ImplementedAsAtanYOverX = true;
    }

    // Vulkan is based off ES 3.0 so the following should all be supported
    shaderCaps->fUsesPrecisionModifiers = true;
    shaderCaps->fFlatInterpolationSupport = true;

    // GrShaderCaps

    shaderCaps->fShaderDerivativeSupport = true;
    shaderCaps->fGeometryShaderSupport = SkToBool(featureFlags & kGeometryShader_GrVkFeatureFlag);

    shaderCaps->fDualSourceBlendingSupport = SkToBool(featureFlags & kDualSrcBlend_GrVkFeatureFlag);
    if (kAMD_VkVendor == properties.vendorID) {
        // Currently DualSourceBlending is not working on AMD. vkCreateGraphicsPipeline fails when
        // using a draw with dual source. Looking into whether it is driver bug or issue with our
        // SPIR-V. Bug skia:6405
        shaderCaps->fDualSourceBlendingSupport = false;
    }

    shaderCaps->fIntegerSupport = true;

    // Assume the minimum precisions mandated by the SPIR-V spec.
    shaderCaps->fShaderPrecisionVaries = true;
    for (int s = 0; s < kGrShaderTypeCount; ++s) {
        auto& highp = shaderCaps->fFloatPrecisions[s][kHigh_GrSLPrecision];
        highp.fLogRangeLow = highp.fLogRangeHigh = 127;
        highp.fBits = 23;

        auto& mediump = shaderCaps->fFloatPrecisions[s][kMedium_GrSLPrecision];
        mediump.fLogRangeLow = mediump.fLogRangeHigh = 14;
        mediump.fBits = 10;

        shaderCaps->fFloatPrecisions[s][kLow_GrSLPrecision] = mediump;
    }
    shaderCaps->initSamplerPrecisionTable();

    shaderCaps->fMaxVertexSamplers =
    shaderCaps->fMaxGeometrySamplers =
    shaderCaps->fMaxFragmentSamplers = SkTMin(
                                       SkTMin(properties.limits.maxPerStageDescriptorSampledImages,
                                              properties.limits.maxPerStageDescriptorSamplers),
                                              (uint32_t)INT_MAX);
    shaderCaps->fMaxCombinedSamplers = SkTMin(
                                       SkTMin(properties.limits.maxDescriptorSetSampledImages,
                                              properties.limits.maxDescriptorSetSamplers),
                                              (uint32_t)INT_MAX);
}

bool stencil_format_supported(const GrVkInterface* interface,
                              VkPhysicalDevice physDev,
                              VkFormat format) {
    VkFormatProperties props;
    memset(&props, 0, sizeof(VkFormatProperties));
    GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
    return SkToBool(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT & props.optimalTilingFeatures);
}

void GrVkCaps::initStencilFormat(const GrVkInterface* interface, VkPhysicalDevice physDev) {
    // List of legal stencil formats (though perhaps not supported on
    // the particular gpu/driver) from most preferred to least. We are guaranteed to have either
    // VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT. VK_FORMAT_D32_SFLOAT_S8_UINT
    // can optionally have 24 unused bits at the end so we assume the total bits is 64.
    static const StencilFormat
                  // internal Format             stencil bits      total bits        packed?
        gS8    = { VK_FORMAT_S8_UINT,            8,                 8,               false },
        gD24S8 = { VK_FORMAT_D24_UNORM_S8_UINT,  8,                32,               true },
        gD32S8 = { VK_FORMAT_D32_SFLOAT_S8_UINT, 8,                64,               true };

    if (stencil_format_supported(interface, physDev, VK_FORMAT_S8_UINT)) {
        fPreferedStencilFormat = gS8;
    } else if (stencil_format_supported(interface, physDev, VK_FORMAT_D24_UNORM_S8_UINT)) {
        fPreferedStencilFormat = gD24S8;
    } else {
        SkASSERT(stencil_format_supported(interface, physDev, VK_FORMAT_D32_SFLOAT_S8_UINT));
        fPreferedStencilFormat = gD32S8;
    }
}

void GrVkCaps::initConfigTable(const GrVkInterface* interface, VkPhysicalDevice physDev) {
    for (int i = 0; i < kGrPixelConfigCnt; ++i) {
        VkFormat format;
        if (GrPixelConfigToVkFormat(static_cast<GrPixelConfig>(i), &format)) {
            fConfigTable[i].init(interface, physDev, format);
        }
    }

    // We currently do not support compressed textures in Vulkan
    const uint16_t kFlagsToRemove = ConfigInfo::kTextureable_Flag|ConfigInfo::kRenderable_Flag;
    fConfigTable[kETC1_GrPixelConfig].fOptimalFlags &= ~kFlagsToRemove;
    fConfigTable[kETC1_GrPixelConfig].fLinearFlags &= ~kFlagsToRemove;
}

void GrVkCaps::ConfigInfo::InitConfigFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags) {
    if (SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & vkFlags) &&
        SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT & vkFlags)) {
        *flags = *flags | kTextureable_Flag;
    }

    if (SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT & vkFlags)) {
        *flags = *flags | kRenderable_Flag;
    }

    if (SkToBool(VK_FORMAT_FEATURE_BLIT_SRC_BIT & vkFlags)) {
        *flags = *flags | kBlitSrc_Flag;
    }

    if (SkToBool(VK_FORMAT_FEATURE_BLIT_DST_BIT & vkFlags)) {
        *flags = *flags | kBlitDst_Flag;
    }
}

void GrVkCaps::ConfigInfo::init(const GrVkInterface* interface,
                                VkPhysicalDevice physDev,
                                VkFormat format) {
    VkFormatProperties props;
    memset(&props, 0, sizeof(VkFormatProperties));
    GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
    InitConfigFlags(props.linearTilingFeatures, &fLinearFlags);
    InitConfigFlags(props.optimalTilingFeatures, &fOptimalFlags);
}
<|endoftext|>


<commit_before>#include "tracking/protocol.hpp"

#include "base/logging.hpp"

#include <iostream>
#include <vector>

using namespace tracking;

extern "C" int LLVMFuzzerTestOneInput(uint8_t const * data, size_t size)
{
  base::ScopedLogLevelChanger scopedLogLevelChanger(base::LCRITICAL);

  std::vector const dataVec(data, data + size);
  Protocol::DecodeHeader(dataVec);
  for (auto const type : {Protocol::PacketType::Error, Protocol::PacketType::AuthV0,
                          Protocol::PacketType::DataV0, Protocol::PacketType::DataV1})
  {
    Protocol::DecodeAuthPacket(type, dataVec);
    Protocol::DecodeDataPacket(type, dataVec);
  }
  return 0;
}
<commit_msg>[tracking] Covering with fuzz tests Protocol::CreateDataPacket() and Protocol::CreateDataPacket().<commit_after>#include "tracking/protocol.hpp"

#include "coding/traffic.hpp"

#include "geometry/latlon.hpp"

#include "base/logging.hpp"

#include <cstdint>
#include <iostream>
#include <iterator>
#include <vector>

using namespace coding;
using namespace tracking;

namespace
{
template <typename T>
T PopType(std::vector<uint8_t> & data)
{
  T t{};
  if (data.empty())
    return t;

  t = *reinterpret_cast<T*>(data.data());
  if (data.size() <= sizeof(T))
    data.clear();
  else
    data.erase(data.begin(), std::next(data.begin(), sizeof(T)));

  return t;
}

TrafficGPSEncoder::DataPoint PopDataPoint(std::vector<uint8_t> & data)
{
  return TrafficGPSEncoder::DataPoint(PopType<uint64_t>(data) /* timestamp */,
                                      ms::LatLon(PopType<double>(data), PopType<double>(data)),
                                      PopType<uint8_t>(data) /* traffic */);
}
}  // namespace

extern "C" int LLVMFuzzerTestOneInput(uint8_t const * data, size_t size)
{
  base::ScopedLogLevelChanger scopedLogLevelChanger(base::LCRITICAL);

  std::vector const dataVec(data, data + size);

  auto dataVecToConv = dataVec;
  Protocol::DataElementsVec dataElementsVec;
  while (!dataVecToConv.empty())
    dataElementsVec.push_back(PopDataPoint(dataVecToConv));
  Protocol::DataElementsCirc dataElementsCirc(dataElementsVec.cbegin(), dataElementsVec.cend());

  Protocol::DecodeHeader(dataVec);
  for (auto const type : {Protocol::PacketType::Error, Protocol::PacketType::AuthV0,
                          Protocol::PacketType::DataV0, Protocol::PacketType::DataV1})
  {
    Protocol::CreateDataPacket(dataElementsVec, type);
    Protocol::CreateDataPacket(dataElementsCirc, type);
    Protocol::DecodeAuthPacket(type, dataVec);
    Protocol::DecodeDataPacket(type, dataVec);
  }
  return 0;
}
<|endoftext|>


<commit_before>
#include <mpi.h>

extern "C" {
#include "cx/syscx.h"
}
#include "cx/fileb.hh"
#include <errno.h>

#include "opt.hh"
#include "pla.hh"
#include "search.hh"
#include "synthesis.hh"
#include "stabilization.hh"
#include "mpidissem.hh"

#define MpiTag_MpiDissem 1
#define MpiTag_Conflict 2

static MpiDissem* mpi_dissem = 0;

static
  void
set_term_flag (int sig)
{
  (void) sig;
  mpi_dissem->terminate();
}

static
  Bool
done_ck (void* dat)
{
  Cx::Table<uint> flat_conflicts;
  ConflictFamily& conflicts = *(ConflictFamily*) dat;

  if (0 == remove("kill-protocon")) {
    mpi_dissem->terminate();
    return 1;
  }
  else {
    errno = 0;
  }

  if (mpi_dissem->done_ck()) {
    return 1;
  }
  while (mpi_dissem->xtest(flat_conflicts)) {
    conflicts.add_conflicts(flat_conflicts);
  }
  conflicts.flush_new_conflicts(flat_conflicts);
  for (uint i = 0; i < flat_conflicts.sz(); ++i) {
    *mpi_dissem << flat_conflicts[i];
  }
  mpi_dissem->maysend();
  return mpi_dissem->done_ck();
}

static
  void
complete_dissemination(ConflictFamily& conflicts)
{
  Cx::Table<uint> flat_conflicts;
  mpi_dissem->done_fo();
  /* DBog1("completing... %u", mpi_dissem->PcIdx); */
  while (mpi_dissem->xwait(flat_conflicts)) {
    /* DBog1("waiting... %u", mpi_dissem->PcIdx); */
    conflicts.add_conflicts(flat_conflicts);
  }
  /* DBog1("done... %u", mpi_dissem->PcIdx); */
}

static
  int
stabilization_search(vector<uint>& ret_actions,
                     const ProtoconFileOpt& infile_opt,
                     const ProtoconOpt& exec_opt,
                     const AddConvergenceOpt& global_opt,
                     const uint PcIdx,
                     const uint NPcs)
{
  bool solution_found = false;
  ConflictFamily conflicts;
  Cx::Table< FlatSet<uint> > flat_conflicts;

  mpi_dissem = new MpiDissem(PcIdx, NPcs, MpiTag_MpiDissem, MPI_COMM_WORLD);

  signal(SIGINT, set_term_flag);
  signal(SIGTERM, set_term_flag);
  MPI_Info mpi_info;
  MPI_Info_create(&mpi_info);

  if (!initialize_conflicts(conflicts, flat_conflicts, exec_opt, global_opt,
                            PcIdx == 0))
  {
    return false;
  }
  conflicts.flush_new_conflicts();

  Sign good = 1;
  AddConvergenceOpt opt(global_opt);
  Cx::OFileB log_ofile;

  opt.sys_pcidx = PcIdx;
  opt.sys_npcs = NPcs;
  if (!!exec_opt.log_ofilename) {
    Cx::String ofilename( exec_opt.log_ofilename );
    ofilename += ".";
    ofilename += PcIdx;
    log_ofile.open(ofilename);
    opt.log = &log_ofile;
  }
  else if (NPcs > 1) {
    opt.log = &Cx::OFile::null();
  }
  //opt.log = &DBogOF;
  //opt.verify_found = false;

  Xn::Sys sys;
  DoLegit(good, "reading file")
  {
    if (exec_opt.task != ProtoconOpt::VerifyTask)
      good = ReadProtoconFile(sys, infile_opt);
  }

  Cx::LgTable<Xn::Sys> systems;
  SynthesisCtx synctx( PcIdx, NPcs );

  synctx.conflicts = conflicts;

  DoLegit(good, "initialization")
  {
    if (exec_opt.task != ProtoconOpt::VerifyTask)
      good = synctx.init(sys, opt);
  }

  PartialSynthesis& synlvl = synctx.base_inst;

  synctx.done_ck_fn = done_ck;
  synctx.done_ck_mem = &synctx.conflicts;

  Cx::Table< Cx::Table<uint> > act_layers;
  if (opt.search_method == opt.RankShuffleSearch)
  {
    DoLegit(good, "ranking actions")
      good =
      rank_actions (act_layers, sys.topology,
                    synlvl.candidates,
                    synlvl.hi_xn,
                    synlvl.hi_invariant);
  }

  if (exec_opt.task != ProtoconOpt::VerifyTask)
  for (uint i = 1; good && i < exec_opt.params.sz(); ++i) {
    ProtoconFileOpt param_infile_opt = infile_opt;
    param_infile_opt.constant_map = exec_opt.params[i].constant_map;

    Xn::Sys& param_sys = systems.grow1();
    param_sys.topology.pfmla_ctx.use_context_of(sys.topology.pfmla_ctx);
    DoLegit(good, "reading param file")
      good = ReadProtoconFile(param_sys, param_infile_opt);
    DoLegit(good, "add param sys")
      good = synctx.add(param_sys);
  }

  for (uint i = 0; good && i < exec_opt.params.sz(); ++i) {
    synlvl[i].no_conflict = !exec_opt.params[i].conflict_ck();
    synlvl[i].no_partial = !exec_opt.params[i].partial_ck();
  }

  if (!good)
    mpi_dissem->terminate();

  DBog1( "BEGIN! %u", PcIdx );

  if (exec_opt.task == ProtoconOpt::VerifyTask)
  {
    for (uint i = PcIdx; i < exec_opt.xfilepaths.sz(); i += NPcs) {
      if (synctx.done_ck())  break;
      Xn::Sys sys;
      ProtoconFileOpt verif_infile_opt( infile_opt );
      verif_infile_opt.file_path = exec_opt.xfilepaths[i].cstr();
      *opt.log << "VERIFYING: " << verif_infile_opt.file_path << opt.log->endl();
      const bool lightweight = !exec_opt.conflicts_ofilepath;
      sys.topology.lightweight = lightweight;
      if (ReadProtoconFile(sys, verif_infile_opt)) {
        StabilizationCkInfo info;
        if (stabilization_ck(*opt.log, sys, lightweight ? 0 : &info)) {
          solution_found = true;
          ret_actions = sys.actions;
          *opt.log << "System is stabilizing." << opt.log->endl();

          if (!!exec_opt.ofilepath) {
            Cx::String filepath( exec_opt.ofilepath + "." + i );
            *opt.log << "Writing system to: " << filepath  << opt.log->endl();
            Cx::OFileB ofb;
            ofb.open(filepath);
            oput_protocon_file(ofb, sys, exec_opt.use_espresso, sys.actions);
          }
        }
        else {
          *opt.log << "System NOT stabilizing." << opt.log->endl();
          if (!lightweight && info.livelock_exists) {
            //synctx.conflicts.add_conflict(FlatSet<uint>(sys.actions));
            synctx.conflicts.add_conflict(FlatSet<uint>(info.livelock_actions));
          }
        }
      }
    }
  }
  if (exec_opt.task == ProtoconOpt::MinimizeConflictsTask)
  {
    for (uint conflict_idx = PcIdx; conflict_idx < flat_conflicts.sz(); conflict_idx += NPcs) {
      uint old_sz = flat_conflicts[conflict_idx].sz();
      if (!synctx.done_ck() && old_sz > 1) {
        *opt.log
          << "pcidx:" << PcIdx
          << " conflict:" << conflict_idx << "/" << flat_conflicts.sz()
          << " sz:" << old_sz
          << opt.log->endl();

        uint new_sz =
          synlvl.add_small_conflict_set(flat_conflicts[conflict_idx]);

        *opt.log
          << "DONE: pcidx:" << PcIdx
          << " conflict:" << conflict_idx << "/" << flat_conflicts.sz()
          << " old_sz:" << old_sz << " new_sz:" << new_sz
          << opt.log->endl();
      }
    }
  }

  vector<uint> actions;
  if (exec_opt.task == ProtoconOpt::SearchTask)
  for (uint trial_idx = 0; !synctx.done_ck() && (opt.ntrials == 0 || trial_idx < opt.ntrials); ++trial_idx)
  {
    bool found = false;
    if (opt.search_method == opt.RankShuffleSearch)
    {
      PartialSynthesis tape( synlvl );
      vector<uint>& candidates = tape.candidates;
      candidates.clear();
      for (uint i = 0; i < act_layers.sz(); ++i) {
        uint off = candidates.size();
        for (uint j = 0; j < act_layers[i].sz(); ++j) {
          candidates.push_back(act_layers[i][j]);
        }
        synctx.urandom.shuffle(&candidates[off], act_layers[i].sz());
      }
      found = try_order_synthesis(actions, tape);
    }
    else
    {
      found = AddConvergence(actions, synlvl, opt);
    }

    if (synctx.done_ck())
    {}
    else if (found)
    {
      if (!global_opt.try_all) {
        mpi_dissem->terminate();
      }
      else if (!!exec_opt.ofilepath) {
        Cx::OFileB ofb;
        ofb.open(exec_opt.ofilepath + "." + PcIdx + "." + trial_idx);
        oput_protocon_file (ofb, sys, exec_opt.use_espresso, actions);
      }
      solution_found = true;
      ret_actions = actions;
      *opt.log << "SOLUTION FOUND!" << opt.log->endl();
    }
    else {
      if (!synctx.conflicts.sat_ck())
        set_term_flag (1);
    }

    synctx.conflicts.oput_conflict_sizes(*opt.log);
    if (opt.search_method == opt.RankShuffleSearch) {
      if (opt.log != &DBogOF) {
        DBogOF << "pcidx:" << PcIdx << " trial:" << trial_idx+1 << " actions:" << actions.size() << '\n';
      }
      *opt.log << "pcidx:" << PcIdx << " trial:" << trial_idx+1 << " actions:" << actions.size() << '\n';
    }
    else {
      if (opt.log != &DBogOF) {
        *opt.log << "pcidx:" << PcIdx << " trial:" << trial_idx+1 << " depth:" << synlvl.failed_bt_level << '\n';
      }
      DBogOF << "pcidx:" << PcIdx << " trial:" << trial_idx+1 << " depth:" << synlvl.failed_bt_level << '\n';
    }
    opt.log->flush();
    DBogOF.flush();

    if (!synctx.done_ck()) {
      Set<uint> impossible( synctx.conflicts.impossible_set );
      impossible &= Set<uint>(synlvl.candidates);
      if (!impossible.empty())
        synlvl.revise_actions(Set<uint>(), impossible);
    }
  }

  if (global_opt.try_all)
    mpi_dissem->terminate();

  complete_dissemination(synctx.conflicts);

  if (!!exec_opt.conflicts_ofilepath) {
    Cx::Table<uint> flattest_conflicts;
    synctx.conflicts.oput_conflict_sizes(*opt.log);
    opt.log->flush();
    if (PcIdx == 0) {
      synctx.conflicts.flush_new_conflicts();
      for (uint source_idx = 1; source_idx < NPcs; ++source_idx) {
        MPI_Status status;
        uint sz = 0;
        MPI_Probe(MPI_ANY_SOURCE, MpiTag_Conflict, MPI_COMM_WORLD, &status);
        MPI_Get_count (&status, MPI_UNSIGNED, (int*) &sz);
        flattest_conflicts.resize(sz);
        MPI_Recv(&flattest_conflicts[0], sz, MPI_UNSIGNED, MPI_ANY_SOURCE,
                 MpiTag_Conflict, MPI_COMM_WORLD, &status);
        synctx.conflicts.add_conflicts(flattest_conflicts);
        synctx.conflicts.flush_new_conflicts();
        synctx.conflicts.oput_conflict_sizes(*opt.log);
        opt.log->flush();
      }

      synctx.conflicts.trim(global_opt.max_conflict_sz);
      oput_conflicts(synctx.conflicts, exec_opt.conflicts_ofilepath);
    }
    else {
      synctx.conflicts.flush_new_conflicts(flattest_conflicts);
      uint sz = flattest_conflicts.sz();
      MPI_Send(&flattest_conflicts[0], sz, MPI_UNSIGNED, 0,
               MpiTag_Conflict, MPI_COMM_WORLD);
    }
  }

  int ret_pc;
  {
    int send_pc = solution_found ? (int)PcIdx : -1;
    ret_pc = send_pc;
    MPI_Allreduce(&send_pc, &ret_pc, MpiTag_MpiDissem,
                  MPI_INT, MPI_MAX, MPI_COMM_WORLD);
  }

  signal(SIGINT, SIG_DFL);
  signal(SIGTERM, SIG_DFL);
  delete mpi_dissem;
  return ret_pc;
}

int main(int argc, char** argv)
{
  MPI_Init (&argc, &argv);
  int argi = (init_sysCx (&argc, &argv), 1);
  (void) argi;
  push_losefn_sysCx ((void (*) ()) MPI_Finalize);
  uint PcIdx = 0;
  uint NPcs = 1;
  MPI_Comm_rank (MPI_COMM_WORLD, (int*) &PcIdx);
  MPI_Comm_size (MPI_COMM_WORLD, (int*) &NPcs);

  AddConvergenceOpt opt;
  ProtoconFileOpt infile_opt;
  ProtoconOpt exec_opt;
  Xn::Sys sys;
  sys.topology.lightweight = true;
  bool good =
    protocon_options
    (sys, argi, argc, argv, opt, infile_opt, exec_opt);
  if (!good)  failout_sysCx ("Bad args.");

  int found_papc =
    stabilization_search(sys.actions, infile_opt, exec_opt, opt, PcIdx, NPcs);
  if (found_papc == (int)PcIdx) {
    DBog1("Solution found! (By PcIdx %u)", PcIdx);
    for (uint i = 0; i < sys.actions.size(); ++i) {
      const Xn::Net& topo = sys.topology;
      Xn::ActSymm act;
      topo.action(act, sys.actions[i]);
      //DBogOF << sys.actions[i] << ' ';
      OPut(DBogOF, act) << '\n';
    }

    if (!exec_opt.ofilepath.empty_ck())
    {
      Cx::OFileB ofb;
      ofb.open(exec_opt.ofilepath);
      oput_protocon_file (ofb, sys, exec_opt.use_espresso);
    }
  }
  else if (found_papc < 0 && PcIdx == 0) {
    DBog0("No solution found...");
  }
  DBogOF.flush();

  lose_sysCx ();
  return 0;
}

<commit_msg>MPI now supports -solution-as-conflict<commit_after>
#include <mpi.h>

extern "C" {
#include "cx/syscx.h"
}
#include "cx/fileb.hh"
#include <errno.h>

#include "opt.hh"
#include "pla.hh"
#include "search.hh"
#include "synthesis.hh"
#include "stabilization.hh"
#include "mpidissem.hh"

#define MpiTag_MpiDissem 1
#define MpiTag_Conflict 2

static MpiDissem* mpi_dissem = 0;

static
  void
set_term_flag (int sig)
{
  (void) sig;
  mpi_dissem->terminate();
}

static
  Bool
done_ck (void* dat)
{
  Cx::Table<uint> flat_conflicts;
  ConflictFamily& conflicts = *(ConflictFamily*) dat;

  if (0 == remove("kill-protocon")) {
    mpi_dissem->terminate();
    return 1;
  }
  else {
    errno = 0;
  }

  if (mpi_dissem->done_ck()) {
    return 1;
  }
  while (mpi_dissem->xtest(flat_conflicts)) {
    conflicts.add_conflicts(flat_conflicts);
  }
  conflicts.flush_new_conflicts(flat_conflicts);
  for (uint i = 0; i < flat_conflicts.sz(); ++i) {
    *mpi_dissem << flat_conflicts[i];
  }
  mpi_dissem->maysend();
  return mpi_dissem->done_ck();
}

static
  void
complete_dissemination(ConflictFamily& conflicts)
{
  Cx::Table<uint> flat_conflicts;
  mpi_dissem->done_fo();
  /* DBog1("completing... %u", mpi_dissem->PcIdx); */
  while (mpi_dissem->xwait(flat_conflicts)) {
    /* DBog1("waiting... %u", mpi_dissem->PcIdx); */
    conflicts.add_conflicts(flat_conflicts);
  }
  /* DBog1("done... %u", mpi_dissem->PcIdx); */
}

static
  int
stabilization_search(vector<uint>& ret_actions,
                     const ProtoconFileOpt& infile_opt,
                     const ProtoconOpt& exec_opt,
                     const AddConvergenceOpt& global_opt,
                     const uint PcIdx,
                     const uint NPcs)
{
  bool solution_found = false;
  ConflictFamily conflicts;
  Cx::Table< FlatSet<uint> > flat_conflicts;

  mpi_dissem = new MpiDissem(PcIdx, NPcs, MpiTag_MpiDissem, MPI_COMM_WORLD);

  signal(SIGINT, set_term_flag);
  signal(SIGTERM, set_term_flag);
  MPI_Info mpi_info;
  MPI_Info_create(&mpi_info);

  if (!initialize_conflicts(conflicts, flat_conflicts, exec_opt, global_opt,
                            PcIdx == 0))
  {
    return false;
  }
  conflicts.flush_new_conflicts();

  Sign good = 1;
  AddConvergenceOpt opt(global_opt);
  Cx::OFileB log_ofile;

  opt.sys_pcidx = PcIdx;
  opt.sys_npcs = NPcs;
  if (!!exec_opt.log_ofilename) {
    Cx::String ofilename( exec_opt.log_ofilename );
    ofilename += ".";
    ofilename += PcIdx;
    log_ofile.open(ofilename);
    opt.log = &log_ofile;
  }
  else if (NPcs > 1) {
    opt.log = &Cx::OFile::null();
  }
  //opt.log = &DBogOF;
  //opt.verify_found = false;

  Xn::Sys sys;
  DoLegit(good, "reading file")
  {
    if (exec_opt.task != ProtoconOpt::VerifyTask)
      good = ReadProtoconFile(sys, infile_opt);
  }

  Cx::LgTable<Xn::Sys> systems;
  SynthesisCtx synctx( PcIdx, NPcs );

  synctx.conflicts = conflicts;

  DoLegit(good, "initialization")
  {
    if (exec_opt.task != ProtoconOpt::VerifyTask)
      good = synctx.init(sys, opt);
  }

  PartialSynthesis& synlvl = synctx.base_inst;

  synctx.done_ck_fn = done_ck;
  synctx.done_ck_mem = &synctx.conflicts;

  Cx::Table< Cx::Table<uint> > act_layers;
  if (opt.search_method == opt.RankShuffleSearch)
  {
    DoLegit(good, "ranking actions")
      good =
      rank_actions (act_layers, sys.topology,
                    synlvl.candidates,
                    synlvl.hi_xn,
                    synlvl.hi_invariant);
  }

  if (exec_opt.task != ProtoconOpt::VerifyTask)
  for (uint i = 1; good && i < exec_opt.params.sz(); ++i) {
    ProtoconFileOpt param_infile_opt = infile_opt;
    param_infile_opt.constant_map = exec_opt.params[i].constant_map;

    Xn::Sys& param_sys = systems.grow1();
    param_sys.topology.pfmla_ctx.use_context_of(sys.topology.pfmla_ctx);
    DoLegit(good, "reading param file")
      good = ReadProtoconFile(param_sys, param_infile_opt);
    DoLegit(good, "add param sys")
      good = synctx.add(param_sys);
  }

  for (uint i = 0; good && i < exec_opt.params.sz(); ++i) {
    synlvl[i].no_conflict = !exec_opt.params[i].conflict_ck();
    synlvl[i].no_partial = !exec_opt.params[i].partial_ck();
  }

  if (!good)
    mpi_dissem->terminate();

  DBog1( "BEGIN! %u", PcIdx );

  if (exec_opt.task == ProtoconOpt::VerifyTask)
  {
    for (uint i = PcIdx; i < exec_opt.xfilepaths.sz(); i += NPcs) {
      if (synctx.done_ck())  break;
      Xn::Sys sys;
      ProtoconFileOpt verif_infile_opt( infile_opt );
      verif_infile_opt.file_path = exec_opt.xfilepaths[i].cstr();
      *opt.log << "VERIFYING: " << verif_infile_opt.file_path << opt.log->endl();
      const bool lightweight = !exec_opt.conflicts_ofilepath;
      sys.topology.lightweight = lightweight;
      if (ReadProtoconFile(sys, verif_infile_opt)) {
        StabilizationCkInfo info;
        if (stabilization_ck(*opt.log, sys, lightweight ? 0 : &info)) {
          solution_found = true;
          ret_actions = sys.actions;
          *opt.log << "System is stabilizing." << opt.log->endl();

          if (!!exec_opt.ofilepath) {
            Cx::String filepath( exec_opt.ofilepath + "." + i );
            *opt.log << "Writing system to: " << filepath  << opt.log->endl();
            Cx::OFileB ofb;
            ofb.open(filepath);
            oput_protocon_file(ofb, sys, exec_opt.use_espresso, sys.actions);
          }
        }
        else {
          *opt.log << "System NOT stabilizing." << opt.log->endl();
          if (!lightweight && info.livelock_exists) {
            //synctx.conflicts.add_conflict(FlatSet<uint>(sys.actions));
            synctx.conflicts.add_conflict(FlatSet<uint>(info.livelock_actions));
          }
        }
      }
    }
  }
  if (exec_opt.task == ProtoconOpt::MinimizeConflictsTask)
  {
    for (uint conflict_idx = PcIdx; conflict_idx < flat_conflicts.sz(); conflict_idx += NPcs) {
      uint old_sz = flat_conflicts[conflict_idx].sz();
      if (!synctx.done_ck() && old_sz > 1) {
        *opt.log
          << "pcidx:" << PcIdx
          << " conflict:" << conflict_idx << "/" << flat_conflicts.sz()
          << " sz:" << old_sz
          << opt.log->endl();

        uint new_sz =
          synlvl.add_small_conflict_set(flat_conflicts[conflict_idx]);

        *opt.log
          << "DONE: pcidx:" << PcIdx
          << " conflict:" << conflict_idx << "/" << flat_conflicts.sz()
          << " old_sz:" << old_sz << " new_sz:" << new_sz
          << opt.log->endl();
      }
    }
  }

  vector<uint> actions;
  if (exec_opt.task == ProtoconOpt::SearchTask)
  for (uint trial_idx = 0; !synctx.done_ck() && (opt.ntrials == 0 || trial_idx < opt.ntrials); ++trial_idx)
  {
    bool found = false;
    if (opt.search_method == opt.RankShuffleSearch)
    {
      PartialSynthesis tape( synlvl );
      vector<uint>& candidates = tape.candidates;
      candidates.clear();
      for (uint i = 0; i < act_layers.sz(); ++i) {
        uint off = candidates.size();
        for (uint j = 0; j < act_layers[i].sz(); ++j) {
          candidates.push_back(act_layers[i][j]);
        }
        synctx.urandom.shuffle(&candidates[off], act_layers[i].sz());
      }
      found = try_order_synthesis(actions, tape);
    }
    else
    {
      found = AddConvergence(actions, synlvl, opt);
    }

    if (synctx.done_ck())
    {}
    else if (found)
    {
      if (opt.solution_as_conflict) {
        FlatSet<uint> flat_actions( actions );
        conflicts.add_conflict(flat_actions);
      }
      if (!global_opt.try_all) {
        mpi_dissem->terminate();
      }
      else if (!!exec_opt.ofilepath) {
        Cx::OFileB ofb;
        ofb.open(exec_opt.ofilepath + "." + PcIdx + "." + trial_idx);
        oput_protocon_file (ofb, sys, exec_opt.use_espresso, actions);
      }
      solution_found = true;
      ret_actions = actions;
      *opt.log << "SOLUTION FOUND!" << opt.log->endl();
    }
    else {
      if (!synctx.conflicts.sat_ck())
        set_term_flag (1);
    }

    synctx.conflicts.oput_conflict_sizes(*opt.log);
    if (opt.search_method == opt.RankShuffleSearch) {
      if (opt.log != &DBogOF) {
        DBogOF << "pcidx:" << PcIdx << " trial:" << trial_idx+1 << " actions:" << actions.size() << '\n';
      }
      *opt.log << "pcidx:" << PcIdx << " trial:" << trial_idx+1 << " actions:" << actions.size() << '\n';
    }
    else {
      if (opt.log != &DBogOF) {
        *opt.log << "pcidx:" << PcIdx << " trial:" << trial_idx+1 << " depth:" << synlvl.failed_bt_level << '\n';
      }
      DBogOF << "pcidx:" << PcIdx << " trial:" << trial_idx+1 << " depth:" << synlvl.failed_bt_level << '\n';
    }
    opt.log->flush();
    DBogOF.flush();

    if (!synctx.done_ck()) {
      Set<uint> impossible( synctx.conflicts.impossible_set );
      impossible &= Set<uint>(synlvl.candidates);
      if (!impossible.empty())
        synlvl.revise_actions(Set<uint>(), impossible);
    }
  }

  if (global_opt.try_all)
    mpi_dissem->terminate();

  complete_dissemination(synctx.conflicts);

  if (!!exec_opt.conflicts_ofilepath) {
    Cx::Table<uint> flattest_conflicts;
    synctx.conflicts.oput_conflict_sizes(*opt.log);
    opt.log->flush();
    if (PcIdx == 0) {
      synctx.conflicts.flush_new_conflicts();
      for (uint source_idx = 1; source_idx < NPcs; ++source_idx) {
        MPI_Status status;
        uint sz = 0;
        MPI_Probe(MPI_ANY_SOURCE, MpiTag_Conflict, MPI_COMM_WORLD, &status);
        MPI_Get_count (&status, MPI_UNSIGNED, (int*) &sz);
        flattest_conflicts.resize(sz);
        MPI_Recv(&flattest_conflicts[0], sz, MPI_UNSIGNED, MPI_ANY_SOURCE,
                 MpiTag_Conflict, MPI_COMM_WORLD, &status);
        synctx.conflicts.add_conflicts(flattest_conflicts);
        synctx.conflicts.flush_new_conflicts();
        synctx.conflicts.oput_conflict_sizes(*opt.log);
        opt.log->flush();
      }

      synctx.conflicts.trim(global_opt.max_conflict_sz);
      oput_conflicts(synctx.conflicts, exec_opt.conflicts_ofilepath);
    }
    else {
      synctx.conflicts.flush_new_conflicts(flattest_conflicts);
      uint sz = flattest_conflicts.sz();
      MPI_Send(&flattest_conflicts[0], sz, MPI_UNSIGNED, 0,
               MpiTag_Conflict, MPI_COMM_WORLD);
    }
  }

  int ret_pc;
  {
    int send_pc = solution_found ? (int)PcIdx : -1;
    ret_pc = send_pc;
    MPI_Allreduce(&send_pc, &ret_pc, MpiTag_MpiDissem,
                  MPI_INT, MPI_MAX, MPI_COMM_WORLD);
  }

  signal(SIGINT, SIG_DFL);
  signal(SIGTERM, SIG_DFL);
  delete mpi_dissem;
  return ret_pc;
}

int main(int argc, char** argv)
{
  MPI_Init (&argc, &argv);
  int argi = (init_sysCx (&argc, &argv), 1);
  (void) argi;
  push_losefn_sysCx ((void (*) ()) MPI_Finalize);
  uint PcIdx = 0;
  uint NPcs = 1;
  MPI_Comm_rank (MPI_COMM_WORLD, (int*) &PcIdx);
  MPI_Comm_size (MPI_COMM_WORLD, (int*) &NPcs);

  AddConvergenceOpt opt;
  ProtoconFileOpt infile_opt;
  ProtoconOpt exec_opt;
  Xn::Sys sys;
  sys.topology.lightweight = true;
  bool good =
    protocon_options
    (sys, argi, argc, argv, opt, infile_opt, exec_opt);
  if (!good)  failout_sysCx ("Bad args.");

  int found_papc =
    stabilization_search(sys.actions, infile_opt, exec_opt, opt, PcIdx, NPcs);
  if (found_papc == (int)PcIdx) {
    DBog1("Solution found! (By PcIdx %u)", PcIdx);
    for (uint i = 0; i < sys.actions.size(); ++i) {
      const Xn::Net& topo = sys.topology;
      Xn::ActSymm act;
      topo.action(act, sys.actions[i]);
      //DBogOF << sys.actions[i] << ' ';
      OPut(DBogOF, act) << '\n';
    }

    if (!exec_opt.ofilepath.empty_ck())
    {
      Cx::OFileB ofb;
      ofb.open(exec_opt.ofilepath);
      oput_protocon_file (ofb, sys, exec_opt.use_espresso);
    }
  }
  else if (found_papc < 0 && PcIdx == 0) {
    DBog0("No solution found...");
  }
  DBogOF.flush();

  lose_sysCx ();
  return 0;
}

<|endoftext|>


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

#include "config.h"

#include "base/command_line.h"
#include "cc/settings.h"
#include "cc/switches.h"

namespace {
static bool s_settingsInitialized = false;

static bool s_perTilePaintingEnabled = false;
static bool s_partialSwapEnabled = false;
static bool s_acceleratedAnimationEnabled = false;
static bool s_pageScalePinchZoomEnabled = false;
static bool s_jankInsteadOfCheckerboard = false;
static bool s_backgroundColorInsteadOfCheckerboard = false;

void reset()
{
    s_settingsInitialized = true;

    s_perTilePaintingEnabled = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kEnablePerTilePainting);
    s_partialSwapEnabled = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kEnablePartialSwap);
    s_acceleratedAnimationEnabled = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kDisableThreadedAnimation);
    s_pageScalePinchZoomEnabled = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kEnablePinchInCompositor);
    s_jankInsteadOfCheckerboard = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kJankInsteadOfCheckerboard);
    s_backgroundColorInsteadOfCheckerboard = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kBackgroundColorInsteadOfCheckerboard);
}

}

namespace cc {

bool Settings::perTilePaintingEnabled()
{
    if (!s_settingsInitialized)
        reset();
    return s_perTilePaintingEnabled;
}

bool Settings::partialSwapEnabled()
{
    if (!s_settingsInitialized)
        reset();
    return s_partialSwapEnabled;
}

bool Settings::acceleratedAnimationEnabled()
{
    if (!s_settingsInitialized)
        reset();
    return s_acceleratedAnimationEnabled;
}

bool Settings::pageScalePinchZoomEnabled()
{
    if (!s_settingsInitialized)
        reset();
    return s_pageScalePinchZoomEnabled;
}

bool Settings::jankInsteadOfCheckerboard()
{
    if (!s_settingsInitialized)
        reset();
    return s_jankInsteadOfCheckerboard;
}

bool Settings::backgroundColorInsteadOfCheckerboard()
{
    if (!s_settingsInitialized)
        reset();
    return s_backgroundColorInsteadOfCheckerboard;
}

void Settings::resetForTest()
{
    reset();
}

void Settings::setPartialSwapEnabled(bool enabled)
{
    if (!s_settingsInitialized)
        reset();
    s_partialSwapEnabled = enabled;
}

void Settings::setPerTilePaintingEnabled(bool enabled)
{
    if (!s_settingsInitialized)
        reset();
    s_partialSwapEnabled = enabled;
}

void Settings::setAcceleratedAnimationEnabled(bool enabled)
{
    if (!s_settingsInitialized)
        reset();
    s_acceleratedAnimationEnabled = enabled;
}

void Settings::setPageScalePinchZoomEnabled(bool enabled)
{
    if (!s_settingsInitialized)
        reset();
    s_pageScalePinchZoomEnabled = enabled;
}

} // namespace cc
<commit_msg>Fix initialisation of s_acceleratedAnimationEnabled flag.<commit_after>// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include "base/command_line.h"
#include "cc/settings.h"
#include "cc/switches.h"

namespace {
static bool s_settingsInitialized = false;

static bool s_perTilePaintingEnabled = false;
static bool s_partialSwapEnabled = false;
static bool s_acceleratedAnimationEnabled = false;
static bool s_pageScalePinchZoomEnabled = false;
static bool s_jankInsteadOfCheckerboard = false;
static bool s_backgroundColorInsteadOfCheckerboard = false;

void reset()
{
    s_settingsInitialized = true;

    s_perTilePaintingEnabled = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kEnablePerTilePainting);
    s_partialSwapEnabled = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kEnablePartialSwap);
    s_acceleratedAnimationEnabled = !CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kDisableThreadedAnimation);
    s_pageScalePinchZoomEnabled = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kEnablePinchInCompositor);
    s_jankInsteadOfCheckerboard = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kJankInsteadOfCheckerboard);
    s_backgroundColorInsteadOfCheckerboard = CommandLine::ForCurrentProcess()->HasSwitch(cc::switches::kBackgroundColorInsteadOfCheckerboard);
}

}

namespace cc {

bool Settings::perTilePaintingEnabled()
{
    if (!s_settingsInitialized)
        reset();
    return s_perTilePaintingEnabled;
}

bool Settings::partialSwapEnabled()
{
    if (!s_settingsInitialized)
        reset();
    return s_partialSwapEnabled;
}

bool Settings::acceleratedAnimationEnabled()
{
    if (!s_settingsInitialized)
        reset();
    return s_acceleratedAnimationEnabled;
}

bool Settings::pageScalePinchZoomEnabled()
{
    if (!s_settingsInitialized)
        reset();
    return s_pageScalePinchZoomEnabled;
}

bool Settings::jankInsteadOfCheckerboard()
{
    if (!s_settingsInitialized)
        reset();
    return s_jankInsteadOfCheckerboard;
}

bool Settings::backgroundColorInsteadOfCheckerboard()
{
    if (!s_settingsInitialized)
        reset();
    return s_backgroundColorInsteadOfCheckerboard;
}

void Settings::resetForTest()
{
    reset();
}

void Settings::setPartialSwapEnabled(bool enabled)
{
    if (!s_settingsInitialized)
        reset();
    s_partialSwapEnabled = enabled;
}

void Settings::setPerTilePaintingEnabled(bool enabled)
{
    if (!s_settingsInitialized)
        reset();
    s_partialSwapEnabled = enabled;
}

void Settings::setAcceleratedAnimationEnabled(bool enabled)
{
    if (!s_settingsInitialized)
        reset();
    s_acceleratedAnimationEnabled = enabled;
}

void Settings::setPageScalePinchZoomEnabled(bool enabled)
{
    if (!s_settingsInitialized)
        reset();
    s_pageScalePinchZoomEnabled = enabled;
}

} // namespace cc
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DropDownFieldDialog.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 09:09:08 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif

#ifndef _WRTSH_HXX
#include <wrtsh.hxx>
#endif
#ifndef _FLDBAS_HXX
#include <fldbas.hxx>
#endif
#ifndef _FLDMGR_HXX
#include <fldmgr.hxx>
#endif
#ifndef _MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _SW_DROPDOWNFIELDDIALOG_HXX
#include <DropDownFieldDialog.hxx>
#endif
#ifndef _FLDDROPDOWN_HXX
#include <flddropdown.hxx>
#endif
#ifndef _FLDUI_HRC
#include <fldui.hrc>
#endif
#ifndef _SW_DROPDOWNFIELDDIALOG_HRC
#include <DropDownFieldDialog.hrc>
#endif

using com::sun::star::uno::Sequence;

/*--------------------------------------------------------------------
    Beschreibung: Feldeinfuegen bearbeiten
 --------------------------------------------------------------------*/

sw::DropDownFieldDialog::DropDownFieldDialog( Window *pParent, SwWrtShell &rS,
                              SwField* pField, BOOL bNextButton ) :

    SvxStandardDialog(pParent,  SW_RES(DLG_FLD_DROPDOWN)),
    aItemsFL(       this, SW_RES( FL_ITEMS       )),
    aListItemsLB(   this, SW_RES( LB_LISTITEMS   )),
    aOKPB(          this, SW_RES( PB_OK          )),
    aCancelPB(      this, SW_RES( PB_CANCEL      )),
    aNextPB(        this, SW_RES( PB_NEXT        )),
    aHelpPB(        this, SW_RES( PB_HELP        )),
    aEditPB(        this, SW_RES( PB_EDIT        )),
    pDropField(0),
    rSh( rS )
{
    Link aButtonLk = LINK(this, DropDownFieldDialog, ButtonHdl);
    aEditPB.SetClickHdl(aButtonLk);
    if( bNextButton )
    {
        aNextPB.Show();
        aNextPB.SetClickHdl(aButtonLk);
    }
    else
    {
        long nDiff = aCancelPB.GetPosPixel().Y() - aOKPB.GetPosPixel().Y();
        Point aPos = aHelpPB.GetPosPixel();
        aPos.Y() -= nDiff;
        aHelpPB.SetPosPixel(aPos);
    }
    if( RES_DROPDOWN == pField->GetTyp()->Which() )
    {
        //
        pDropField = (SwDropDownField*)pField;
        String sTitle = GetText();
        sTitle += pDropField->GetPar2();
        SetText(sTitle);
        Sequence<rtl::OUString> aItems = pDropField->GetItemSequence();
        const rtl::OUString* pArray = aItems.getConstArray();
        for(sal_Int32 i = 0; i < aItems.getLength(); i++)
            aListItemsLB.InsertEntry(pArray[i]);
        aListItemsLB.SelectEntry(pDropField->GetSelectedItem());
    }

    BOOL bEnable = !rSh.IsCrsrReadonly();
    aOKPB.Enable( bEnable );

    aListItemsLB.GrabFocus();
    FreeResource();
}

sw::DropDownFieldDialog::~DropDownFieldDialog()
{
}

/*--------------------------------------------------------------------

 --------------------------------------------------------------------*/

void sw::DropDownFieldDialog::Apply()
{
    if(pDropField)
    {
        String sSelect = aListItemsLB.GetSelectEntry();
        if(pDropField->GetPar1() != sSelect)
        {
            rSh.StartAllAction();

            SwDropDownField * pCopy = (SwDropDownField *) pDropField->Copy();

            pCopy->SetPar1(sSelect);
            rSh.SwEditShell::UpdateFlds(*pCopy);

            delete pCopy;

            rSh.SetUndoNoResetModified();
            rSh.EndAllAction();
        }
    }
}
/* -----------------17.06.2003 10:50-----------------

 --------------------------------------------------*/
IMPL_LINK(sw::DropDownFieldDialog, ButtonHdl, PushButton*, pButton)
{
    EndDialog(&aNextPB == pButton ? RET_OK : RET_YES );
    return 0;
}

<commit_msg>INTEGRATION: CWS swwarnings (1.6.222); FILE MERGED 2007/05/29 12:45:03 os 1.6.222.3: RESYNC: (1.6-1.7); FILE MERGED 2007/04/11 07:03:23 tl 1.6.222.2: #i69287# warning-free code 2007/03/05 12:45:41 tl 1.6.222.1: #i69287# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DropDownFieldDialog.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 11:45:32 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif

#ifndef _WRTSH_HXX
#include <wrtsh.hxx>
#endif
#ifndef _FLDBAS_HXX
#include <fldbas.hxx>
#endif
#ifndef _FLDMGR_HXX
#include <fldmgr.hxx>
#endif
#ifndef _MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _SW_DROPDOWNFIELDDIALOG_HXX
#include <DropDownFieldDialog.hxx>
#endif
#ifndef _FLDDROPDOWN_HXX
#include <flddropdown.hxx>
#endif
#ifndef _FLDUI_HRC
#include <fldui.hrc>
#endif
#ifndef _SW_DROPDOWNFIELDDIALOG_HRC
#include <DropDownFieldDialog.hrc>
#endif

using namespace ::com::sun::star;

/*--------------------------------------------------------------------
    Beschreibung: Feldeinfuegen bearbeiten
 --------------------------------------------------------------------*/

sw::DropDownFieldDialog::DropDownFieldDialog( Window *pParent, SwWrtShell &rS,
                              SwField* pField, BOOL bNextButton ) :

    SvxStandardDialog(pParent,  SW_RES(DLG_FLD_DROPDOWN)),
    aItemsFL(       this, SW_RES( FL_ITEMS       )),
    aListItemsLB(   this, SW_RES( LB_LISTITEMS   )),

    aOKPB(          this, SW_RES( PB_OK          )),
    aCancelPB(      this, SW_RES( PB_CANCEL      )),
    aNextPB(        this, SW_RES( PB_NEXT        )),
    aHelpPB(        this, SW_RES( PB_HELP        )),

    aEditPB(        this, SW_RES( PB_EDIT        )),

    rSh( rS ),
    pDropField(0)
{
    Link aButtonLk = LINK(this, DropDownFieldDialog, ButtonHdl);
    aEditPB.SetClickHdl(aButtonLk);
    if( bNextButton )
    {
        aNextPB.Show();
        aNextPB.SetClickHdl(aButtonLk);
    }
    else
    {
        long nDiff = aCancelPB.GetPosPixel().Y() - aOKPB.GetPosPixel().Y();
        Point aPos = aHelpPB.GetPosPixel();
        aPos.Y() -= nDiff;
        aHelpPB.SetPosPixel(aPos);
    }
    if( RES_DROPDOWN == pField->GetTyp()->Which() )
    {
        //
        pDropField = (SwDropDownField*)pField;
        String sTitle = GetText();
        sTitle += pDropField->GetPar2();
        SetText(sTitle);
        uno::Sequence< rtl::OUString > aItems = pDropField->GetItemSequence();
        const rtl::OUString* pArray = aItems.getConstArray();
        for(sal_Int32 i = 0; i < aItems.getLength(); i++)
            aListItemsLB.InsertEntry(pArray[i]);
        aListItemsLB.SelectEntry(pDropField->GetSelectedItem());
    }

    BOOL bEnable = !rSh.IsCrsrReadonly();
    aOKPB.Enable( bEnable );

    aListItemsLB.GrabFocus();
    FreeResource();
}

sw::DropDownFieldDialog::~DropDownFieldDialog()
{
}

/*--------------------------------------------------------------------

 --------------------------------------------------------------------*/

void sw::DropDownFieldDialog::Apply()
{
    if(pDropField)
    {
        String sSelect = aListItemsLB.GetSelectEntry();
        if(pDropField->GetPar1() != sSelect)
        {
            rSh.StartAllAction();

            SwDropDownField * pCopy = (SwDropDownField *) pDropField->Copy();

            pCopy->SetPar1(sSelect);
            rSh.SwEditShell::UpdateFlds(*pCopy);

            delete pCopy;

            rSh.SetUndoNoResetModified();
            rSh.EndAllAction();
        }
    }
}
/* -----------------17.06.2003 10:50-----------------

 --------------------------------------------------*/
IMPL_LINK(sw::DropDownFieldDialog, ButtonHdl, PushButton*, pButton)
{
    EndDialog(&aNextPB == pButton ? RET_OK : RET_YES );
    return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2011-2016 The Cryptonote developers
// Copyright (c) 2015-2016 XDN developers
// Copyright (c) 2016-2022 The Karbowanec developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <QDebug>
#include <QThread>
#include <QUrl>
#include <QtConcurrent/QtConcurrent>
#include <QtConcurrent/QtConcurrentRun>
#include <QDebug>

#include "MiningFrame.h"
#include "MainWindow.h"
#include "Settings.h"
#include "WalletAdapter.h"
#include "NodeAdapter.h"
#include "CryptoNoteWrapper.h"
#include "CurrencyAdapter.h"
#include "Settings.h"
#include "Logging/LoggerManager.h"
#include "LoggerAdapter.h"

#include "ui_miningframe.h"

namespace WalletGui {

const quint32 HASHRATE_TIMER_INTERVAL = 1000;
const quint32 MINER_ROUTINE_TIMER_INTERVAL = 60000;

MiningFrame::MiningFrame(QWidget* _parent) :
    QFrame(_parent), m_ui(new Ui::MiningFrame),
    m_miner(new Miner(this, LoggerAdapter::instance().getLoggerManager())),
    m_soloHashRateTimerId(-1) {
  m_ui->setupUi(this);
  initCpuCoreList();

  QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
  fixedFont.setStyleHint(QFont::TypeWriter);
  m_ui->m_minerLog->setFont(fixedFont);

  m_ui->m_startSolo->setEnabled(false);
  m_ui->m_stopSolo->setEnabled(false);

  NodeType node = NodeAdapter::instance().getNodeType();
  if (node != NodeType::IN_PROCESS) {
    m_ui->m_startSolo->setDisabled(true);
  }

  m_ui->m_hashRateChart->addGraph();
  m_ui->m_hashRateChart->graph(0)->setScatterStyle(QCPScatterStyle::ssDot);
  m_ui->m_hashRateChart->graph(0)->setLineStyle(QCPGraph::lsLine);
  m_ui->m_hashRateChart->graph()->setPen(QPen(QRgb(0xe3e1e3)));
  m_ui->m_hashRateChart->graph()->setBrush(QBrush(QRgb(0x0b1620)));

  QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
  dateTicker->setDateTimeFormat("hh:mm:ss");
  m_ui->m_hashRateChart->xAxis->setTicker(dateTicker);
  m_ui->m_hashRateChart->yAxis->setRange(0, m_maxHr);
  m_ui->m_hashRateChart->yAxis->setLabel("Hashrate");
  m_ui->m_hashRateChart->xAxis->setTickPen(QPen(QRgb(0xe3e1e3)));
  m_ui->m_hashRateChart->xAxis->setLabelColor(QRgb(0xe3e1e3));

  // make top and right axes visible but without ticks and labels
  m_ui->m_hashRateChart->xAxis2->setVisible(true);
  m_ui->m_hashRateChart->yAxis2->setVisible(true);
  m_ui->m_hashRateChart->xAxis2->setTicks(false);
  m_ui->m_hashRateChart->yAxis2->setTicks(false);
  m_ui->m_hashRateChart->xAxis2->setTickLabels(false);
  m_ui->m_hashRateChart->yAxis2->setTickLabels(false);

  m_ui->m_hashRateChart->setBackground(QBrush(QRgb(0x19232d)));

  addPoint(QDateTime::currentDateTime().toTime_t(), 0);
  plot();

  connect(&WalletAdapter::instance(), &WalletAdapter::walletCloseCompletedSignal, this, &MiningFrame::walletClosed, Qt::QueuedConnection);
  connect(&WalletAdapter::instance(), &WalletAdapter::walletInitCompletedSignal, this, &MiningFrame::walletOpened, Qt::QueuedConnection);
  connect(&WalletAdapter::instance(), &WalletAdapter::walletActualBalanceUpdatedSignal, this, &MiningFrame::updateBalance, Qt::QueuedConnection);
  connect(&WalletAdapter::instance(), &WalletAdapter::walletPendingBalanceUpdatedSignal, this, &MiningFrame::updatePendingBalance, Qt::QueuedConnection);
  connect(&WalletAdapter::instance(), &WalletAdapter::walletSynchronizationCompletedSignal, this, &MiningFrame::onSynchronizationCompleted, Qt::QueuedConnection);
  connect(&NodeAdapter::instance(), &NodeAdapter::localBlockchainUpdatedSignal, this, &MiningFrame::onBlockHeightUpdated, Qt::QueuedConnection);
  connect(&*m_miner, &Miner::minerMessageSignal, this, &MiningFrame::updateMinerLog, Qt::QueuedConnection);
}

MiningFrame::~MiningFrame() {
  stopSolo();
}

void MiningFrame::addPoint(double x, double y)
{
  m_hX.append(x);
  m_hY.append(y);

  // scroll plot
  if (m_hX.size() > 1000 || m_hY.size() > 1000) {
    m_hX.pop_front();
    m_hY.pop_front();
  }
}

void MiningFrame::plot()
{
  m_maxHr = std::max<double>(m_maxHr, m_hY.at(m_hY.size()-1));
  m_ui->m_hashRateChart->graph(0)->setData(m_hX, m_hY);
  m_ui->m_hashRateChart->xAxis->setRange(m_hX.at(0), m_hX.at(m_hX.size()-1));
  m_ui->m_hashRateChart->yAxis->setRange(0, m_maxHr);
  m_ui->m_hashRateChart->replot();
  m_ui->m_hashRateChart->update();
}

void MiningFrame::timerEvent(QTimerEvent* _event) {
  if (_event->timerId() == m_soloHashRateTimerId) {
    m_miner->merge_hr();
    double hashRate = m_miner->get_speed();
    if (hashRate == 0) {
      return;
    }
    m_ui->m_soloLabel->setText(tr("Mining"));
    m_ui->m_hashratelcdNumber->display(hashRate);
    addPoint(QDateTime::currentDateTime().toTime_t(), hashRate);
    plot();

    return;
  }
  if (_event->timerId() == m_minerRoutineTimerId) {
    m_miner->on_idle();
  }

  QFrame::timerEvent(_event);
}

void MiningFrame::initCpuCoreList() {
  quint16 threads = Settings::instance().getMiningThreads();
  int cpuCoreCount = QThread::idealThreadCount();
  if (cpuCoreCount == -1) {
      cpuCoreCount = 2;
  }

  if (threads > 0) {
    m_ui->m_cpuCoresSpin->setValue(threads);
  } else {
    m_ui->m_cpuCoresSpin->setValue((cpuCoreCount - 1) / 2);
  }

  m_ui->m_cpuCoresSpin->setMaximum(cpuCoreCount);
  m_ui->m_cpuCoresSpin->setMinimum(1);
  m_ui->m_cpuDial->setMaximum(cpuCoreCount);
  m_ui->m_cpuDial->setMinimum(1);
}

void MiningFrame::walletOpened() {
  if(m_solo_mining)
    stopSolo();

  m_wallet_closed = false;

  quint64 difficulty = NodeAdapter::instance().getDifficulty();
  m_ui->m_difficulty->setText(QString(tr("%1")).arg(difficulty));
}

void MiningFrame::walletClosed() {
  stopSolo();
  m_wallet_closed = true;
  m_ui->m_startSolo->setEnabled(false);
  m_ui->m_stopSolo->isChecked();

  // TODO: consider setting all dials to zeroes
}

void MiningFrame::startSolo() {
  quint64 difficulty = NodeAdapter::instance().getDifficulty();
  m_ui->m_difficulty->setText(QString(tr("%1")).arg(difficulty));

  m_miner->start(m_ui->m_cpuCoresSpin->value());
  m_ui->m_soloLabel->setText(tr("Starting..."));
  m_soloHashRateTimerId = startTimer(HASHRATE_TIMER_INTERVAL);
  m_minerRoutineTimerId = startTimer(MINER_ROUTINE_TIMER_INTERVAL);
  addPoint(QDateTime::currentDateTime().toTime_t(), 0);
  m_ui->m_startSolo->setChecked(true);
  m_ui->m_startSolo->setEnabled(false);
  m_ui->m_stopSolo->setEnabled(true);
  m_ui->m_cpuCoresSpin->setEnabled(false);
  m_ui->m_cpuDial->setEnabled(false);
  m_solo_mining = true;
}

void MiningFrame::stopSolo() {
  if(m_solo_mining) {
    killTimer(m_soloHashRateTimerId);
    m_soloHashRateTimerId = -1;
    killTimer(m_minerRoutineTimerId);
    m_minerRoutineTimerId = -1;
    m_miner->stop();
    addPoint(QDateTime::currentDateTime().toTime_t(), 0);
    m_ui->m_soloLabel->setText(tr("Stopped"));
    m_ui->m_hashratelcdNumber->display(0.0);
    m_ui->m_startSolo->setEnabled(true);
    m_ui->m_stopSolo->setEnabled(false);
    m_ui->m_cpuCoresSpin->setEnabled(true);
    m_ui->m_cpuDial->setEnabled(true);
    m_solo_mining = false;
  }
}

void MiningFrame::enableSolo() {
  m_sychronized = true;
  if (!m_solo_mining) {
    m_ui->m_startSolo->setEnabled(true);
    m_ui->m_stopSolo->setEnabled(false);
    if (Settings::instance().isMiningOnLaunchEnabled() && m_sychronized) {
      startSolo();
    }
  }
}

void MiningFrame::startStopSoloClicked(QAbstractButton* _button) {
  if (_button == m_ui->m_startSolo && m_ui->m_startSolo->isChecked() && m_wallet_closed != true) {
    startSolo();
  } else if (m_wallet_closed == true && _button == m_ui->m_stopSolo && m_ui->m_stopSolo->isChecked()) {
    m_ui->m_startSolo->setEnabled(false);
    stopSolo();
  } else if (_button == m_ui->m_stopSolo && m_ui->m_stopSolo->isChecked()) {
    stopSolo();
  }
}

void MiningFrame::setMiningThreads() {
  Settings::instance().setMiningThreads(m_ui->m_cpuCoresSpin->value());
}

void MiningFrame::onBlockHeightUpdated() {
  m_miner->on_block_chain_update();

  quint64 difficulty = NodeAdapter::instance().getDifficulty();
  m_ui->m_difficulty->setText(QString(tr("%1")).arg(difficulty));
}

void MiningFrame::onSynchronizationCompleted() {
  NodeType node = NodeAdapter::instance().getNodeType();
  if (node != NodeType::IN_PROCESS) {
    m_ui->m_startSolo->setEnabled(false);
    return;
  }
  if (!m_miner->is_mining()) {
    m_ui->m_startSolo->setEnabled(true);
  }
}

void MiningFrame::updateBalance(quint64 _balance) {
  Q_UNUSED(_balance);
}

void MiningFrame::updatePendingBalance(quint64 _balance) {
  Q_UNUSED(_balance);
}

void MiningFrame::updateMinerLog(const QString& _message) {
  QString message = _message + "\n";
  m_miner_log += message;

  m_ui->m_minerLog->setPlainText(m_miner_log);

  QScrollBar *sb = m_ui->m_minerLog->verticalScrollBar();
  sb->setValue(sb->maximum());
}

void MiningFrame::coreDealTurned(int _cores) {
  qDebug() << "Cores " << _cores;
  QTimer::singleShot(600, [this, _cores]() {
    Settings::instance().setMiningThreads(_cores);
  } );
}

}
<commit_msg>Remove unneeded debug mess<commit_after>// Copyright (c) 2011-2016 The Cryptonote developers
// Copyright (c) 2015-2016 XDN developers
// Copyright (c) 2016-2022 The Karbowanec developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <QDebug>
#include <QThread>
#include <QUrl>
#include <QtConcurrent/QtConcurrent>
#include <QtConcurrent/QtConcurrentRun>
#include <QDebug>

#include "MiningFrame.h"
#include "MainWindow.h"
#include "Settings.h"
#include "WalletAdapter.h"
#include "NodeAdapter.h"
#include "CryptoNoteWrapper.h"
#include "CurrencyAdapter.h"
#include "Settings.h"
#include "Logging/LoggerManager.h"
#include "LoggerAdapter.h"

#include "ui_miningframe.h"

namespace WalletGui {

const quint32 HASHRATE_TIMER_INTERVAL = 1000;
const quint32 MINER_ROUTINE_TIMER_INTERVAL = 60000;

MiningFrame::MiningFrame(QWidget* _parent) :
    QFrame(_parent), m_ui(new Ui::MiningFrame),
    m_miner(new Miner(this, LoggerAdapter::instance().getLoggerManager())),
    m_soloHashRateTimerId(-1) {
  m_ui->setupUi(this);
  initCpuCoreList();

  QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
  fixedFont.setStyleHint(QFont::TypeWriter);
  m_ui->m_minerLog->setFont(fixedFont);

  m_ui->m_startSolo->setEnabled(false);
  m_ui->m_stopSolo->setEnabled(false);

  NodeType node = NodeAdapter::instance().getNodeType();
  if (node != NodeType::IN_PROCESS) {
    m_ui->m_startSolo->setDisabled(true);
  }

  m_ui->m_hashRateChart->addGraph();
  m_ui->m_hashRateChart->graph(0)->setScatterStyle(QCPScatterStyle::ssDot);
  m_ui->m_hashRateChart->graph(0)->setLineStyle(QCPGraph::lsLine);
  m_ui->m_hashRateChart->graph()->setPen(QPen(QRgb(0xe3e1e3)));
  m_ui->m_hashRateChart->graph()->setBrush(QBrush(QRgb(0x0b1620)));

  QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
  dateTicker->setDateTimeFormat("hh:mm:ss");
  m_ui->m_hashRateChart->xAxis->setTicker(dateTicker);
  m_ui->m_hashRateChart->yAxis->setRange(0, m_maxHr);
  m_ui->m_hashRateChart->yAxis->setLabel("Hashrate");
  m_ui->m_hashRateChart->xAxis->setTickPen(QPen(QRgb(0xe3e1e3)));
  m_ui->m_hashRateChart->xAxis->setLabelColor(QRgb(0xe3e1e3));

  // make top and right axes visible but without ticks and labels
  m_ui->m_hashRateChart->xAxis2->setVisible(true);
  m_ui->m_hashRateChart->yAxis2->setVisible(true);
  m_ui->m_hashRateChart->xAxis2->setTicks(false);
  m_ui->m_hashRateChart->yAxis2->setTicks(false);
  m_ui->m_hashRateChart->xAxis2->setTickLabels(false);
  m_ui->m_hashRateChart->yAxis2->setTickLabels(false);

  m_ui->m_hashRateChart->setBackground(QBrush(QRgb(0x19232d)));

  addPoint(QDateTime::currentDateTime().toTime_t(), 0);
  plot();

  connect(&WalletAdapter::instance(), &WalletAdapter::walletCloseCompletedSignal, this, &MiningFrame::walletClosed, Qt::QueuedConnection);
  connect(&WalletAdapter::instance(), &WalletAdapter::walletInitCompletedSignal, this, &MiningFrame::walletOpened, Qt::QueuedConnection);
  connect(&WalletAdapter::instance(), &WalletAdapter::walletActualBalanceUpdatedSignal, this, &MiningFrame::updateBalance, Qt::QueuedConnection);
  connect(&WalletAdapter::instance(), &WalletAdapter::walletPendingBalanceUpdatedSignal, this, &MiningFrame::updatePendingBalance, Qt::QueuedConnection);
  connect(&WalletAdapter::instance(), &WalletAdapter::walletSynchronizationCompletedSignal, this, &MiningFrame::onSynchronizationCompleted, Qt::QueuedConnection);
  connect(&NodeAdapter::instance(), &NodeAdapter::localBlockchainUpdatedSignal, this, &MiningFrame::onBlockHeightUpdated, Qt::QueuedConnection);
  connect(&*m_miner, &Miner::minerMessageSignal, this, &MiningFrame::updateMinerLog, Qt::QueuedConnection);
}

MiningFrame::~MiningFrame() {
  stopSolo();
}

void MiningFrame::addPoint(double x, double y)
{
  m_hX.append(x);
  m_hY.append(y);

  // scroll plot
  if (m_hX.size() > 1000 || m_hY.size() > 1000) {
    m_hX.pop_front();
    m_hY.pop_front();
  }
}

void MiningFrame::plot()
{
  m_maxHr = std::max<double>(m_maxHr, m_hY.at(m_hY.size()-1));
  m_ui->m_hashRateChart->graph(0)->setData(m_hX, m_hY);
  m_ui->m_hashRateChart->xAxis->setRange(m_hX.at(0), m_hX.at(m_hX.size()-1));
  m_ui->m_hashRateChart->yAxis->setRange(0, m_maxHr);
  m_ui->m_hashRateChart->replot();
  m_ui->m_hashRateChart->update();
}

void MiningFrame::timerEvent(QTimerEvent* _event) {
  if (_event->timerId() == m_soloHashRateTimerId) {
    m_miner->merge_hr();
    double hashRate = m_miner->get_speed();
    if (hashRate == 0) {
      return;
    }
    m_ui->m_soloLabel->setText(tr("Mining"));
    m_ui->m_hashratelcdNumber->display(hashRate);
    addPoint(QDateTime::currentDateTime().toTime_t(), hashRate);
    plot();

    return;
  }
  if (_event->timerId() == m_minerRoutineTimerId) {
    m_miner->on_idle();
  }

  QFrame::timerEvent(_event);
}

void MiningFrame::initCpuCoreList() {
  quint16 threads = Settings::instance().getMiningThreads();
  int cpuCoreCount = QThread::idealThreadCount();
  if (cpuCoreCount == -1) {
      cpuCoreCount = 2;
  }

  if (threads > 0) {
    m_ui->m_cpuCoresSpin->setValue(threads);
  } else {
    m_ui->m_cpuCoresSpin->setValue((cpuCoreCount - 1) / 2);
  }

  m_ui->m_cpuCoresSpin->setMaximum(cpuCoreCount);
  m_ui->m_cpuCoresSpin->setMinimum(1);
  m_ui->m_cpuDial->setMaximum(cpuCoreCount);
  m_ui->m_cpuDial->setMinimum(1);
}

void MiningFrame::walletOpened() {
  if(m_solo_mining)
    stopSolo();

  m_wallet_closed = false;

  quint64 difficulty = NodeAdapter::instance().getDifficulty();
  m_ui->m_difficulty->setText(QString(tr("%1")).arg(difficulty));
}

void MiningFrame::walletClosed() {
  stopSolo();
  m_wallet_closed = true;
  m_ui->m_startSolo->setEnabled(false);
  m_ui->m_stopSolo->isChecked();

  // TODO: consider setting all dials to zeroes
}

void MiningFrame::startSolo() {
  quint64 difficulty = NodeAdapter::instance().getDifficulty();
  m_ui->m_difficulty->setText(QString(tr("%1")).arg(difficulty));

  m_miner->start(m_ui->m_cpuCoresSpin->value());
  m_ui->m_soloLabel->setText(tr("Starting..."));
  m_soloHashRateTimerId = startTimer(HASHRATE_TIMER_INTERVAL);
  m_minerRoutineTimerId = startTimer(MINER_ROUTINE_TIMER_INTERVAL);
  addPoint(QDateTime::currentDateTime().toTime_t(), 0);
  m_ui->m_startSolo->setChecked(true);
  m_ui->m_startSolo->setEnabled(false);
  m_ui->m_stopSolo->setEnabled(true);
  m_ui->m_cpuCoresSpin->setEnabled(false);
  m_ui->m_cpuDial->setEnabled(false);
  m_solo_mining = true;
}

void MiningFrame::stopSolo() {
  if(m_solo_mining) {
    killTimer(m_soloHashRateTimerId);
    m_soloHashRateTimerId = -1;
    killTimer(m_minerRoutineTimerId);
    m_minerRoutineTimerId = -1;
    m_miner->stop();
    addPoint(QDateTime::currentDateTime().toTime_t(), 0);
    m_ui->m_soloLabel->setText(tr("Stopped"));
    m_ui->m_hashratelcdNumber->display(0.0);
    m_ui->m_startSolo->setEnabled(true);
    m_ui->m_stopSolo->setEnabled(false);
    m_ui->m_cpuCoresSpin->setEnabled(true);
    m_ui->m_cpuDial->setEnabled(true);
    m_solo_mining = false;
  }
}

void MiningFrame::enableSolo() {
  m_sychronized = true;
  if (!m_solo_mining) {
    m_ui->m_startSolo->setEnabled(true);
    m_ui->m_stopSolo->setEnabled(false);
    if (Settings::instance().isMiningOnLaunchEnabled() && m_sychronized) {
      startSolo();
    }
  }
}

void MiningFrame::startStopSoloClicked(QAbstractButton* _button) {
  if (_button == m_ui->m_startSolo && m_ui->m_startSolo->isChecked() && m_wallet_closed != true) {
    startSolo();
  } else if (m_wallet_closed == true && _button == m_ui->m_stopSolo && m_ui->m_stopSolo->isChecked()) {
    m_ui->m_startSolo->setEnabled(false);
    stopSolo();
  } else if (_button == m_ui->m_stopSolo && m_ui->m_stopSolo->isChecked()) {
    stopSolo();
  }
}

void MiningFrame::setMiningThreads() {
  Settings::instance().setMiningThreads(m_ui->m_cpuCoresSpin->value());
}

void MiningFrame::onBlockHeightUpdated() {
  m_miner->on_block_chain_update();

  quint64 difficulty = NodeAdapter::instance().getDifficulty();
  m_ui->m_difficulty->setText(QString(tr("%1")).arg(difficulty));
}

void MiningFrame::onSynchronizationCompleted() {
  NodeType node = NodeAdapter::instance().getNodeType();
  if (node != NodeType::IN_PROCESS) {
    m_ui->m_startSolo->setEnabled(false);
    return;
  }
  if (!m_miner->is_mining()) {
    m_ui->m_startSolo->setEnabled(true);
  }
}

void MiningFrame::updateBalance(quint64 _balance) {
  Q_UNUSED(_balance);
}

void MiningFrame::updatePendingBalance(quint64 _balance) {
  Q_UNUSED(_balance);
}

void MiningFrame::updateMinerLog(const QString& _message) {
  QString message = _message + "\n";
  m_miner_log += message;

  m_ui->m_minerLog->setPlainText(m_miner_log);

  QScrollBar *sb = m_ui->m_minerLog->verticalScrollBar();
  sb->setValue(sb->maximum());
}

void MiningFrame::coreDealTurned(int _cores) {
  QTimer::singleShot(600, [this, _cores]() {
    Settings::instance().setMiningThreads(_cores);
  } );
}

}
<|endoftext|>


<commit_before>/*
 * strcheck.hpp
 *  The class to check if strings are integer, decimal, or real number
 *
 *  written by janus_wel<janus.wel.3@gmail.com>
 *  This source code is in public domain, and has NO WARRANTY.
 * */

#ifndef STRCHECK_HPP
#define STRCHECK_HPP

#include <cstring>
#include <locale>
#include <string>

namespace util {
    namespace string {
        template<typename Char> struct numeric_traits;
        template<> struct numeric_traits<char> {
            typedef char    char_type;
            static const char_type positive = '+';
            static const char_type negative = '-';
        };
        template<> struct numeric_traits<wchar_t> {
            typedef wchar_t char_type;
            static const char_type positive = L'+';
            static const char_type negative = L'-';
        };

        template<   typename Char,
                    typename CharTraits = std::char_traits<Char>,
                    typename NumTraits = numeric_traits<Char> >
        class basic_check {
            public:
                typedef Char                            char_type;
                typedef std::basic_string<char_type>    string_type;
                typedef std::ctype<char_type>           ctype_type;
                typedef std::numpunct<char_type>        numpunct_type;

            private:
                std::locale loc;

            public:
                // constructor
                explicit basic_check(void) : loc(std::locale()) {}
                explicit basic_check(const std::locale& loc) : loc(loc) {}

            private:
                const ctype_type& ctype(void) const {
                    static const ctype_type& ctype =
                        std::use_facet<ctype_type>(loc);
                    return ctype;
                }

                char_type decimal_point(void) const {
                    static const char_type decimal_point =
                        std::use_facet<numpunct_type>(loc).decimal_point();
                    return decimal_point;
                }

            public:
                bool is_integer(const char_type* const str) const {
                    const char_type* const first =
                        (  (str[0] == NumTraits::positive)
                         | (str[0] == NumTraits::negative)) ? str + 1 : str;
                    const char_type* const last =
                        first + CharTraits::length(first);
                    const char_type* const found =
                        ctype().scan_not(ctype_type::digit, first, last);

                    return found == last;
                }

                bool is_integer(const string_type& str) const {
                    return is_integer(str.c_str());
                }

                bool is_decimal(const char_type* const str) const {
                    const char_type* const first =
                        (  (str[0] == NumTraits::positive)
                         | (str[0] == NumTraits::negative)) ? str + 1 : str;

                    const char_type* const point =
                        CharTraits::find(   first,
                                            CharTraits::length(first),
                                            decimal_point());

                    if (point == 0 || point == first) return false;

                    const char_type* integer =
                        ctype().scan_not(ctype_type::digit, first, point);
                    return ((integer == point) & is_integer(point + 1));
                }

                bool is_decimal(const string_type& str) const {
                    return is_decimal(str.c_str());
                }

                bool is_real(const char_type* const str) const {
                    return (is_integer(str) | is_decimal(str));
                }

                bool is_real(const string_type& str) const {
                    return is_real(str.c_str());
                }
        };

        typedef basic_check<char>       check;
        typedef basic_check<wchar_t>    wcheck;
    }
}

#endif // STRCHECK_HPP

<commit_msg>Update latest version<commit_after>/*
 * strcheck.hpp
 *  The class to check if strings are integer, decimal, or real number
 *
 *  written by janus_wel<janus.wel.3@gmail.com>
 *  This source code is in public domain, and has NO WARRANTY.
 * */

#ifndef STRCHECK_HPP
#define STRCHECK_HPP

#include <cstring>
#include <locale>
#include <string>

namespace util {
    namespace string {
        template<typename Char> struct numeric_traits;
        template<> struct numeric_traits<char> {
            typedef char    char_type;
            static const char_type positive = '+';
            static const char_type negative = '-';
        };
        template<> struct numeric_traits<wchar_t> {
            typedef wchar_t char_type;
            static const char_type positive = L'+';
            static const char_type negative = L'-';
        };

        template<   typename Char,
                    typename CharTraits = std::char_traits<Char>,
                    typename NumTraits = numeric_traits<Char> >
        class basic_check {
            public:
                typedef Char                            char_type;
                typedef std::basic_string<char_type>    string_type;
                typedef std::ctype<char_type>           ctype_type;
                typedef std::numpunct<char_type>        numpunct_type;

            private:
                std::locale loc;

            public:
                // constructor
                explicit basic_check(void) : loc(std::locale()) {}
                explicit basic_check(const std::locale& loc) : loc(loc) {}

            private:
                const ctype_type& ctype(void) const {
                    static const ctype_type& ctype =
                        std::use_facet<ctype_type>(loc);
                    return ctype;
                }

                char_type decimal_point(void) const {
                    static const char_type decimal_point =
                        std::use_facet<numpunct_type>(loc).decimal_point();
                    return decimal_point;
                }

            public:
                bool is_positive(const char_type* const str) const {
                    return !is_negative(str);
                }

                bool is_positive(const string_type& str) const {
                    return is_positive(str.c_str());
                }

                bool is_negative(const char_type* const str) const {
                    return str[0] == NumTraits::negative;
                }

                bool is_negative(const string_type& str) const {
                    return is_negative(str.c_str());
                }

                bool is_integer(const char_type* const str) const {
                    const char_type* const first =
                        (  (str[0] == NumTraits::positive)
                         | (str[0] == NumTraits::negative)) ? str + 1 : str;
                    const char_type* const last =
                        first + CharTraits::length(first);
                    const char_type* const found =
                        ctype().scan_not(ctype_type::digit, first, last);

                    return found == last;
                }

                bool is_integer(const string_type& str) const {
                    return is_integer(str.c_str());
                }

                bool is_decimal(const char_type* const str) const {
                    const char_type* const first =
                        (  (str[0] == NumTraits::positive)
                         | (str[0] == NumTraits::negative)) ? str + 1 : str;

                    const char_type* const point =
                        CharTraits::find(   first,
                                            CharTraits::length(first),
                                            decimal_point());

                    if (point == 0 || point == first) return false;

                    const char_type* integer =
                        ctype().scan_not(ctype_type::digit, first, point);
                    return ((integer == point) & is_integer(point + 1));
                }

                bool is_decimal(const string_type& str) const {
                    return is_decimal(str.c_str());
                }

                bool is_real(const char_type* const str) const {
                    return (is_integer(str) | is_decimal(str));
                }

                bool is_real(const string_type& str) const {
                    return is_real(str.c_str());
                }
        };

        typedef basic_check<char>       check;
        typedef basic_check<wchar_t>    wcheck;
    }
}

#endif // STRCHECK_HPP

<|endoftext|>