<commit_before>/*
This file is part of HadesMem.
Copyright (C) 2010 Joshua Boyce (aka RaptorFactor, Cypherjb, Cypher, Chazwazza).
<http://www.raptorfactor.com/> <raptorfactor@raptorfactor.com>

HadesMem is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

HadesMem 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with HadesMem.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

// C++ Standard Library
#include <memory>

// Windows API
#include <Windows.h>

// DirectX
#include <d3d9.h>
#include <d3dx9.h>

// Hades
#include "Renderer.hpp"
#include "HadesCommon/Error.hpp"

namespace Hades
{
  namespace D3D9
  {
    class IDirect3DDevice9Hook : public IDirect3DDevice9
    {
    public:
      class Error : public virtual HadesError
      { };

      explicit IDirect3DDevice9Hook(
        IDirect3D9* pD3D9,
        IDirect3DDevice9* pDevice,
        D3DPRESENT_PARAMETERS* pPresentParams);

      // IUnknown methods
      STDMETHOD(QueryInterface)(
        THIS_ REFIID riid,
        void** ppvObj);

      STDMETHOD_(ULONG, AddRef)(
        THIS);

      STDMETHOD_(ULONG, Release)(
        THIS);

      // IDirect3DDevice9 methods
      STDMETHOD(TestCooperativeLevel)(
        THIS);

      STDMETHOD_(UINT, GetAvailableTextureMem)(
        THIS);

      STDMETHOD(EvictManagedResources)(
        THIS);

      STDMETHOD(GetDirect3D)(
        THIS_ IDirect3D9** ppD3D9);

      STDMETHOD(GetDeviceCaps)(
        THIS_ D3DCAPS9* pCaps);

      STDMETHOD(GetDisplayMode)(
        THIS_ UINT iSwapChain,
        D3DDISPLAYMODE* pMode);

      STDMETHOD(GetCreationParameters)(
        THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters);

      STDMETHOD(SetCursorProperties)(
        THIS_ UINT XHotSpot,
        UINT YHotSpot,
        IDirect3DSurface9* pCursorBitmap);

      STDMETHOD_(void, SetCursorPosition)(
        THIS_ int X,
        int Y,
        DWORD Flags);

      STDMETHOD_(BOOL, ShowCursor)(
        THIS_ BOOL bShow);

      STDMETHOD(CreateAdditionalSwapChain)(
        THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,
        IDirect3DSwapChain9** pSwapChain);

      STDMETHOD(GetSwapChain)(
        THIS_ UINT iSwapChain,
        IDirect3DSwapChain9** pSwapChain);

      STDMETHOD_(UINT, GetNumberOfSwapChains)(
        THIS);

      STDMETHOD(Reset)(
        THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters);

      STDMETHOD(Present)(
        THIS_ CONST RECT* pSourceRect,
        CONST RECT* pDestRect,
        HWND hDestWindowOverride,
        CONST RGNDATA* pDirtyRegion);

      STDMETHOD(GetBackBuffer)(
        THIS_ UINT iSwapChain,
        UINT iBackBuffer,
        D3DBACKBUFFER_TYPE Type,
        IDirect3DSurface9** ppBackBuffer);

      STDMETHOD(GetRasterStatus)(
        THIS_ UINT iSwapChain,
        D3DRASTER_STATUS* pRasterStatus);

      STDMETHOD(SetDialogBoxMode)(
        THIS_ BOOL bEnableDialogs);

      STDMETHOD_(void, SetGammaRamp)(
        THIS_ UINT iSwapChain,
        DWORD Flags,
        CONST D3DGAMMARAMP* pRamp);

      STDMETHOD_(void, GetGammaRamp)(
        THIS_ UINT iSwapChain,
        D3DGAMMARAMP* pRamp);

      STDMETHOD(CreateTexture)(
        THIS_ UINT Width,
        UINT Height,
        UINT Levels,
        DWORD Usage,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DTexture9** ppTexture,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateVolumeTexture)(
        THIS_ UINT Width,UINT Height,
        UINT Depth,
        UINT Levels,
        DWORD Usage,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DVolumeTexture9** ppVolumeTexture,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateCubeTexture)(
        THIS_ UINT EdgeLength,
        UINT Levels,
        DWORD Usage,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DCubeTexture9** ppCubeTexture,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateVertexBuffer)(
        THIS_ UINT Length,
        DWORD Usage,
        DWORD FVF,
        D3DPOOL Pool,
        IDirect3DVertexBuffer9** ppVertexBuffer,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateIndexBuffer)(
        THIS_ UINT Length,
        DWORD Usage,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DIndexBuffer9** ppIndexBuffer,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateRenderTarget)(
        THIS_ UINT Width,
        UINT Height,
        D3DFORMAT Format,
        D3DMULTISAMPLE_TYPE MultiSample,
        DWORD MultisampleQuality,
        BOOL Lockable,
        IDirect3DSurface9** ppSurface,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateDepthStencilSurface)(
        THIS_ UINT Width,
        UINT Height,
        D3DFORMAT Format,
        D3DMULTISAMPLE_TYPE MultiSample,
        DWORD MultisampleQuality,
        BOOL Discard,
        IDirect3DSurface9** ppSurface,
        HANDLE* pSharedHandle);

      STDMETHOD(UpdateSurface)(
        THIS_ IDirect3DSurface9* pSourceSurface,
        CONST RECT* pSourceRect,
        IDirect3DSurface9* pDestinationSurface,
        CONST POINT* pDestPoint);

      STDMETHOD(UpdateTexture)(
        THIS_ IDirect3DBaseTexture9* pSourceTexture,
        IDirect3DBaseTexture9* pDestinationTexture);

      STDMETHOD(GetRenderTargetData)(
        THIS_ IDirect3DSurface9* pRenderTarget,
        IDirect3DSurface9* pDestSurface);

      STDMETHOD(GetFrontBufferData)(
        THIS_ UINT iSwapChain,
        IDirect3DSurface9* pDestSurface);

      STDMETHOD(StretchRect)(
        THIS_ IDirect3DSurface9* pSourceSurface,
        CONST RECT* pSourceRect,
        IDirect3DSurface9* pDestSurface,
        CONST RECT* pDestRect,
        D3DTEXTUREFILTERTYPE Filter);

      STDMETHOD(ColorFill)(
        THIS_ IDirect3DSurface9* pSurface,
        CONST RECT* pRect,
        D3DCOLOR color);

      STDMETHOD(CreateOffscreenPlainSurface)(
        THIS_ UINT Width,
        UINT Height,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DSurface9** ppSurface,
        HANDLE* pSharedHandle);

      STDMETHOD(SetRenderTarget)(
        THIS_ DWORD RenderTargetIndex,
        IDirect3DSurface9* pRenderTarget);

      STDMETHOD(GetRenderTarget)(
        THIS_ DWORD RenderTargetIndex,
        IDirect3DSurface9** ppRenderTarget);

      STDMETHOD(SetDepthStencilSurface)(
        THIS_ IDirect3DSurface9* pNewZStencil);

      STDMETHOD(GetDepthStencilSurface)(
        THIS_ IDirect3DSurface9** ppZStencilSurface);

      STDMETHOD(BeginScene)(
        THIS);

      STDMETHOD(EndScene)(
        THIS);

      STDMETHOD(Clear)(
        THIS_ DWORD Count,
        CONST D3DRECT* pRects,
        DWORD Flags,
        D3DCOLOR Color,
        float Z,
        DWORD Stencil);

      STDMETHOD(SetTransform)(
        THIS_ D3DTRANSFORMSTATETYPE State,
        CONST D3DMATRIX* pMatrix);

      STDMETHOD(GetTransform)(
        THIS_ D3DTRANSFORMSTATETYPE State,
        D3DMATRIX* pMatrix);

      STDMETHOD(MultiplyTransform)(
        THIS_ D3DTRANSFORMSTATETYPE,
        CONST D3DMATRIX*);

      STDMETHOD(SetViewport)(
        THIS_ CONST D3DVIEWPORT9* pViewport);

      STDMETHOD(GetViewport)(
        THIS_ D3DVIEWPORT9* pViewport);

      STDMETHOD(SetMaterial)(
        THIS_ CONST D3DMATERIAL9* pMaterial);

      STDMETHOD(GetMaterial)(
        THIS_ D3DMATERIAL9* pMaterial);

      STDMETHOD(SetLight)(
        THIS_ DWORD Index,
        CONST D3DLIGHT9*);

      STDMETHOD(GetLight)(
        THIS_ DWORD Index,
        D3DLIGHT9*);

      STDMETHOD(LightEnable)(
        THIS_ DWORD Index,
        BOOL Enable);

      STDMETHOD(GetLightEnable)(
        THIS_ DWORD Index,
        BOOL* pEnable);

      STDMETHOD(SetClipPlane)(
        THIS_ DWORD Index,
        CONST float* pPlane);

      STDMETHOD(GetClipPlane)(
        THIS_ DWORD Index,
        float* pPlane);

      STDMETHOD(SetRenderState)(
        THIS_ D3DRENDERSTATETYPE State,
        DWORD Value);

      STDMETHOD(GetRenderState)(
        THIS_ D3DRENDERSTATETYPE State,
        DWORD* pValue);

      STDMETHOD(CreateStateBlock)(
        THIS_ D3DSTATEBLOCKTYPE Type,
        IDirect3DStateBlock9** ppSB);

      STDMETHOD(BeginStateBlock)(
        THIS);

      STDMETHOD(EndStateBlock)(
        THIS_ IDirect3DStateBlock9** ppSB);

      STDMETHOD(SetClipStatus)(
        THIS_ CONST D3DCLIPSTATUS9* pClipStatus);

      STDMETHOD(GetClipStatus)(
        THIS_ D3DCLIPSTATUS9* pClipStatus);

      STDMETHOD(GetTexture)(
        THIS_ DWORD Stage,
        IDirect3DBaseTexture9** ppTexture);

      STDMETHOD(SetTexture)(
        THIS_ DWORD Stage,
        IDirect3DBaseTexture9* pTexture);

      STDMETHOD(GetTextureStageState)(
        THIS_ DWORD Stage,
        D3DTEXTURESTAGESTATETYPE Type,
        DWORD* pValue);

      STDMETHOD(SetTextureStageState)(
        THIS_ DWORD Stage,
        D3DTEXTURESTAGESTATETYPE Type,
        DWORD Value);

      STDMETHOD(GetSamplerState)(
        THIS_ DWORD Sampler,
        D3DSAMPLERSTATETYPE Type,
        DWORD* pValue);

      STDMETHOD(SetSamplerState)(
        THIS_ DWORD Sampler,
        D3DSAMPLERSTATETYPE Type,
        DWORD Value);

      STDMETHOD(ValidateDevice)(
        THIS_ DWORD* pNumPasses);

      STDMETHOD(SetPaletteEntries)(
        THIS_ UINT PaletteNumber,
        CONST PALETTEENTRY* pEntries);

      STDMETHOD(GetPaletteEntries)(
        THIS_ UINT PaletteNumber,
        PALETTEENTRY* pEntries);

      STDMETHOD(SetCurrentTexturePalette)(
        THIS_ UINT PaletteNumber);

      STDMETHOD(GetCurrentTexturePalette)(
        THIS_ UINT *PaletteNumber);

      STDMETHOD(SetScissorRect)(
        THIS_ CONST RECT* pRect);

      STDMETHOD(GetScissorRect)(
        THIS_ RECT* pRect);

      STDMETHOD(SetSoftwareVertexProcessing)(
        THIS_ BOOL bSoftware);

      STDMETHOD_(BOOL, GetSoftwareVertexProcessing)(
        THIS);

      STDMETHOD(SetNPatchMode)(
        THIS_ float nSegments);

      STDMETHOD_(float, GetNPatchMode)(
        THIS);

      STDMETHOD(DrawPrimitive)(
        THIS_ D3DPRIMITIVETYPE PrimitiveType,
        UINT StartVertex,
        UINT PrimitiveCount);

      STDMETHOD(DrawIndexedPrimitive)(
        THIS_ D3DPRIMITIVETYPE,
        INT BaseVertexIndex,
        UINT MinVertexIndex,
        UINT NumVertices,
        UINT startIndex,
        UINT primCount);

      STDMETHOD(DrawPrimitiveUP)(
        THIS_ D3DPRIMITIVETYPE PrimitiveType,
        UINT PrimitiveCount,
        CONST void* pVertexStreamZeroData,
        UINT VertexStreamZeroStride);

      STDMETHOD(DrawIndexedPrimitiveUP)(
        THIS_ D3DPRIMITIVETYPE PrimitiveType,
        UINT MinVertexIndex,
        UINT NumVertices,
        UINT PrimitiveCount,
        CONST void* pIndexData,
        D3DFORMAT IndexDataFormat,
        CONST void* pVertexStreamZeroData,
        UINT VertexStreamZeroStride);

      STDMETHOD(ProcessVertices)(
        THIS_ UINT SrcStartIndex,
        UINT DestIndex,
        UINT VertexCount,
        IDirect3DVertexBuffer9* pDestBuffer,
        IDirect3DVertexDeclaration9* pVertexDecl,
        DWORD Flags);

      STDMETHOD(CreateVertexDeclaration)(
        THIS_ CONST D3DVERTEXELEMENT9* pVertexElements,
        IDirect3DVertexDeclaration9** ppDecl);

      STDMETHOD(SetVertexDeclaration)(
        THIS_ IDirect3DVertexDeclaration9* pDecl);

      STDMETHOD(GetVertexDeclaration)(
        THIS_ IDirect3DVertexDeclaration9** ppDecl);

      STDMETHOD(SetFVF)(
        THIS_ DWORD FVF);

      STDMETHOD(GetFVF)(
        THIS_ DWORD* pFVF);

      STDMETHOD(CreateVertexShader)(
        THIS_ CONST DWORD* pFunction,
        IDirect3DVertexShader9** ppShader);

      STDMETHOD(SetVertexShader)(
        THIS_ IDirect3DVertexShader9* pShader);

      STDMETHOD(GetVertexShader)(
        THIS_ IDirect3DVertexShader9** ppShader);

      STDMETHOD(SetVertexShaderConstantF)(
        THIS_ UINT StartRegister,
        CONST float* pConstantData,
        UINT Vector4fCount);

      STDMETHOD(GetVertexShaderConstantF)(
        THIS_ UINT StartRegister,
        float* pConstantData,
        UINT Vector4fCount);

      STDMETHOD(SetVertexShaderConstantI)(
        THIS_ UINT StartRegister,
        CONST int* pConstantData,
        UINT Vector4iCount);

      STDMETHOD(GetVertexShaderConstantI)(
        THIS_ UINT StartRegister,
        int* pConstantData,
        UINT Vector4iCount);

      STDMETHOD(SetVertexShaderConstantB)(
        THIS_ UINT StartRegister,
        CONST BOOL* pConstantData,
        UINT BoolCount);

      STDMETHOD(GetVertexShaderConstantB)(
        THIS_ UINT StartRegister,
        BOOL* pConstantData,
         UINT BoolCount);

      STDMETHOD(SetStreamSource)(
        THIS_ UINT StreamNumber,
        IDirect3DVertexBuffer9* pStreamData,
        UINT OffsetInBytes,
        UINT Stride);

      STDMETHOD(GetStreamSource)(
        THIS_ UINT StreamNumber,
        IDirect3DVertexBuffer9** ppStreamData,
        UINT* pOffsetInBytes,
        UINT* pStride);

      STDMETHOD(SetStreamSourceFreq)(
        THIS_ UINT StreamNumber,
        UINT Setting);

      STDMETHOD(GetStreamSourceFreq)(
        THIS_ UINT StreamNumber,
        UINT* pSetting);

      STDMETHOD(SetIndices)(
        THIS_ IDirect3DIndexBuffer9* pIndexData);

      STDMETHOD(GetIndices)(
        THIS_ IDirect3DIndexBuffer9** ppIndexData);

      STDMETHOD(CreatePixelShader)(
        THIS_ CONST DWORD* pFunction,
        IDirect3DPixelShader9** ppShader);

      STDMETHOD(SetPixelShader)(
        THIS_ IDirect3DPixelShader9* pShader);

      STDMETHOD(GetPixelShader)(
        THIS_ IDirect3DPixelShader9** ppShader);

      STDMETHOD(SetPixelShaderConstantF)(
        THIS_ UINT StartRegister,
        CONST float* pConstantData,
        UINT Vector4fCount);

      STDMETHOD(GetPixelShaderConstantF)(
        THIS_ UINT StartRegister,
        float* pConstantData,
        UINT Vector4fCount);

      STDMETHOD(SetPixelShaderConstantI)(
        THIS_ UINT StartRegister,
        CONST int* pConstantData,
        UINT Vector4iCount);

      STDMETHOD(GetPixelShaderConstantI)(
        THIS_ UINT StartRegister,
        int* pConstantData,
        UINT Vector4iCount);

      STDMETHOD(SetPixelShaderConstantB)(
        THIS_ UINT StartRegister,
        CONST BOOL* pConstantData,
        UINT  BoolCount);

      STDMETHOD(GetPixelShaderConstantB)(
        THIS_ UINT StartRegister,
        BOOL* pConstantData,
        UINT BoolCount);

      STDMETHOD(DrawRectPatch)(
        THIS_ UINT Handle,
        CONST float* pNumSegs,
        CONST D3DRECTPATCH_INFO* pRectPatchInfo);

      STDMETHOD(DrawTriPatch)(
        THIS_ UINT Handle,
        CONST float* pNumSegs,
        CONST D3DTRIPATCH_INFO* pTriPatchInfo);

      STDMETHOD(DeletePatch)(
        THIS_ UINT Handle);

      STDMETHOD(CreateQuery)(
        THIS_ D3DQUERYTYPE Type,
        IDirect3DQuery9** ppQuery);

    private:
      IDirect3D9* m_pD3D;
      IDirect3DDevice9* m_pDevice;
      D3DPRESENT_PARAMETERS m_PresentParams;
      UINT m_RefCount;

      std::shared_ptr<GUI::D3D9Renderer> m_pRenderer;
    };
  }
}
  <commit_msg>* Todo note.<commit_after>/*
This file is part of HadesMem.
Copyright (C) 2010 Joshua Boyce (aka RaptorFactor, Cypherjb, Cypher, Chazwazza).
<http://www.raptorfactor.com/> <raptorfactor@raptorfactor.com>

HadesMem is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

HadesMem 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with HadesMem.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

// C++ Standard Library
#include <memory>

// Windows API
#include <Windows.h>

// DirectX
#include <d3d9.h>
#include <d3dx9.h>

// Hades
#include "Renderer.hpp"
#include "HadesCommon/Error.hpp"

namespace Hades
{
  namespace D3D9
  {
    // Todo: Decouple device and renderer objects

    class IDirect3DDevice9Hook : public IDirect3DDevice9
    {
    public:
      class Error : public virtual HadesError
      { };

      explicit IDirect3DDevice9Hook(
        IDirect3D9* pD3D9,
        IDirect3DDevice9* pDevice,
        D3DPRESENT_PARAMETERS* pPresentParams);

      // IUnknown methods
      STDMETHOD(QueryInterface)(
        THIS_ REFIID riid,
        void** ppvObj);

      STDMETHOD_(ULONG, AddRef)(
        THIS);

      STDMETHOD_(ULONG, Release)(
        THIS);

      // IDirect3DDevice9 methods
      STDMETHOD(TestCooperativeLevel)(
        THIS);

      STDMETHOD_(UINT, GetAvailableTextureMem)(
        THIS);

      STDMETHOD(EvictManagedResources)(
        THIS);

      STDMETHOD(GetDirect3D)(
        THIS_ IDirect3D9** ppD3D9);

      STDMETHOD(GetDeviceCaps)(
        THIS_ D3DCAPS9* pCaps);

      STDMETHOD(GetDisplayMode)(
        THIS_ UINT iSwapChain,
        D3DDISPLAYMODE* pMode);

      STDMETHOD(GetCreationParameters)(
        THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters);

      STDMETHOD(SetCursorProperties)(
        THIS_ UINT XHotSpot,
        UINT YHotSpot,
        IDirect3DSurface9* pCursorBitmap);

      STDMETHOD_(void, SetCursorPosition)(
        THIS_ int X,
        int Y,
        DWORD Flags);

      STDMETHOD_(BOOL, ShowCursor)(
        THIS_ BOOL bShow);

      STDMETHOD(CreateAdditionalSwapChain)(
        THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,
        IDirect3DSwapChain9** pSwapChain);

      STDMETHOD(GetSwapChain)(
        THIS_ UINT iSwapChain,
        IDirect3DSwapChain9** pSwapChain);

      STDMETHOD_(UINT, GetNumberOfSwapChains)(
        THIS);

      STDMETHOD(Reset)(
        THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters);

      STDMETHOD(Present)(
        THIS_ CONST RECT* pSourceRect,
        CONST RECT* pDestRect,
        HWND hDestWindowOverride,
        CONST RGNDATA* pDirtyRegion);

      STDMETHOD(GetBackBuffer)(
        THIS_ UINT iSwapChain,
        UINT iBackBuffer,
        D3DBACKBUFFER_TYPE Type,
        IDirect3DSurface9** ppBackBuffer);

      STDMETHOD(GetRasterStatus)(
        THIS_ UINT iSwapChain,
        D3DRASTER_STATUS* pRasterStatus);

      STDMETHOD(SetDialogBoxMode)(
        THIS_ BOOL bEnableDialogs);

      STDMETHOD_(void, SetGammaRamp)(
        THIS_ UINT iSwapChain,
        DWORD Flags,
        CONST D3DGAMMARAMP* pRamp);

      STDMETHOD_(void, GetGammaRamp)(
        THIS_ UINT iSwapChain,
        D3DGAMMARAMP* pRamp);

      STDMETHOD(CreateTexture)(
        THIS_ UINT Width,
        UINT Height,
        UINT Levels,
        DWORD Usage,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DTexture9** ppTexture,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateVolumeTexture)(
        THIS_ UINT Width,UINT Height,
        UINT Depth,
        UINT Levels,
        DWORD Usage,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DVolumeTexture9** ppVolumeTexture,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateCubeTexture)(
        THIS_ UINT EdgeLength,
        UINT Levels,
        DWORD Usage,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DCubeTexture9** ppCubeTexture,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateVertexBuffer)(
        THIS_ UINT Length,
        DWORD Usage,
        DWORD FVF,
        D3DPOOL Pool,
        IDirect3DVertexBuffer9** ppVertexBuffer,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateIndexBuffer)(
        THIS_ UINT Length,
        DWORD Usage,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DIndexBuffer9** ppIndexBuffer,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateRenderTarget)(
        THIS_ UINT Width,
        UINT Height,
        D3DFORMAT Format,
        D3DMULTISAMPLE_TYPE MultiSample,
        DWORD MultisampleQuality,
        BOOL Lockable,
        IDirect3DSurface9** ppSurface,
        HANDLE* pSharedHandle);

      STDMETHOD(CreateDepthStencilSurface)(
        THIS_ UINT Width,
        UINT Height,
        D3DFORMAT Format,
        D3DMULTISAMPLE_TYPE MultiSample,
        DWORD MultisampleQuality,
        BOOL Discard,
        IDirect3DSurface9** ppSurface,
        HANDLE* pSharedHandle);

      STDMETHOD(UpdateSurface)(
        THIS_ IDirect3DSurface9* pSourceSurface,
        CONST RECT* pSourceRect,
        IDirect3DSurface9* pDestinationSurface,
        CONST POINT* pDestPoint);

      STDMETHOD(UpdateTexture)(
        THIS_ IDirect3DBaseTexture9* pSourceTexture,
        IDirect3DBaseTexture9* pDestinationTexture);

      STDMETHOD(GetRenderTargetData)(
        THIS_ IDirect3DSurface9* pRenderTarget,
        IDirect3DSurface9* pDestSurface);

      STDMETHOD(GetFrontBufferData)(
        THIS_ UINT iSwapChain,
        IDirect3DSurface9* pDestSurface);

      STDMETHOD(StretchRect)(
        THIS_ IDirect3DSurface9* pSourceSurface,
        CONST RECT* pSourceRect,
        IDirect3DSurface9* pDestSurface,
        CONST RECT* pDestRect,
        D3DTEXTUREFILTERTYPE Filter);

      STDMETHOD(ColorFill)(
        THIS_ IDirect3DSurface9* pSurface,
        CONST RECT* pRect,
        D3DCOLOR color);

      STDMETHOD(CreateOffscreenPlainSurface)(
        THIS_ UINT Width,
        UINT Height,
        D3DFORMAT Format,
        D3DPOOL Pool,
        IDirect3DSurface9** ppSurface,
        HANDLE* pSharedHandle);

      STDMETHOD(SetRenderTarget)(
        THIS_ DWORD RenderTargetIndex,
        IDirect3DSurface9* pRenderTarget);

      STDMETHOD(GetRenderTarget)(
        THIS_ DWORD RenderTargetIndex,
        IDirect3DSurface9** ppRenderTarget);

      STDMETHOD(SetDepthStencilSurface)(
        THIS_ IDirect3DSurface9* pNewZStencil);

      STDMETHOD(GetDepthStencilSurface)(
        THIS_ IDirect3DSurface9** ppZStencilSurface);

      STDMETHOD(BeginScene)(
        THIS);

      STDMETHOD(EndScene)(
        THIS);

      STDMETHOD(Clear)(
        THIS_ DWORD Count,
        CONST D3DRECT* pRects,
        DWORD Flags,
        D3DCOLOR Color,
        float Z,
        DWORD Stencil);

      STDMETHOD(SetTransform)(
        THIS_ D3DTRANSFORMSTATETYPE State,
        CONST D3DMATRIX* pMatrix);

      STDMETHOD(GetTransform)(
        THIS_ D3DTRANSFORMSTATETYPE State,
        D3DMATRIX* pMatrix);

      STDMETHOD(MultiplyTransform)(
        THIS_ D3DTRANSFORMSTATETYPE,
        CONST D3DMATRIX*);

      STDMETHOD(SetViewport)(
        THIS_ CONST D3DVIEWPORT9* pViewport);

      STDMETHOD(GetViewport)(
        THIS_ D3DVIEWPORT9* pViewport);

      STDMETHOD(SetMaterial)(
        THIS_ CONST D3DMATERIAL9* pMaterial);

      STDMETHOD(GetMaterial)(
        THIS_ D3DMATERIAL9* pMaterial);

      STDMETHOD(SetLight)(
        THIS_ DWORD Index,
        CONST D3DLIGHT9*);

      STDMETHOD(GetLight)(
        THIS_ DWORD Index,
        D3DLIGHT9*);

      STDMETHOD(LightEnable)(
        THIS_ DWORD Index,
        BOOL Enable);

      STDMETHOD(GetLightEnable)(
        THIS_ DWORD Index,
        BOOL* pEnable);

      STDMETHOD(SetClipPlane)(
        THIS_ DWORD Index,
        CONST float* pPlane);

      STDMETHOD(GetClipPlane)(
        THIS_ DWORD Index,
        float* pPlane);

      STDMETHOD(SetRenderState)(
        THIS_ D3DRENDERSTATETYPE State,
        DWORD Value);

      STDMETHOD(GetRenderState)(
        THIS_ D3DRENDERSTATETYPE State,
        DWORD* pValue);

      STDMETHOD(CreateStateBlock)(
        THIS_ D3DSTATEBLOCKTYPE Type,
        IDirect3DStateBlock9** ppSB);

      STDMETHOD(BeginStateBlock)(
        THIS);

      STDMETHOD(EndStateBlock)(
        THIS_ IDirect3DStateBlock9** ppSB);

      STDMETHOD(SetClipStatus)(
        THIS_ CONST D3DCLIPSTATUS9* pClipStatus);

      STDMETHOD(GetClipStatus)(
        THIS_ D3DCLIPSTATUS9* pClipStatus);

      STDMETHOD(GetTexture)(
        THIS_ DWORD Stage,
        IDirect3DBaseTexture9** ppTexture);

      STDMETHOD(SetTexture)(
        THIS_ DWORD Stage,
        IDirect3DBaseTexture9* pTexture);

      STDMETHOD(GetTextureStageState)(
        THIS_ DWORD Stage,
        D3DTEXTURESTAGESTATETYPE Type,
        DWORD* pValue);

      STDMETHOD(SetTextureStageState)(
        THIS_ DWORD Stage,
        D3DTEXTURESTAGESTATETYPE Type,
        DWORD Value);

      STDMETHOD(GetSamplerState)(
        THIS_ DWORD Sampler,
        D3DSAMPLERSTATETYPE Type,
        DWORD* pValue);

      STDMETHOD(SetSamplerState)(
        THIS_ DWORD Sampler,
        D3DSAMPLERSTATETYPE Type,
        DWORD Value);

      STDMETHOD(ValidateDevice)(
        THIS_ DWORD* pNumPasses);

      STDMETHOD(SetPaletteEntries)(
        THIS_ UINT PaletteNumber,
        CONST PALETTEENTRY* pEntries);

      STDMETHOD(GetPaletteEntries)(
        THIS_ UINT PaletteNumber,
        PALETTEENTRY* pEntries);

      STDMETHOD(SetCurrentTexturePalette)(
        THIS_ UINT PaletteNumber);

      STDMETHOD(GetCurrentTexturePalette)(
        THIS_ UINT *PaletteNumber);

      STDMETHOD(SetScissorRect)(
        THIS_ CONST RECT* pRect);

      STDMETHOD(GetScissorRect)(
        THIS_ RECT* pRect);

      STDMETHOD(SetSoftwareVertexProcessing)(
        THIS_ BOOL bSoftware);

      STDMETHOD_(BOOL, GetSoftwareVertexProcessing)(
        THIS);

      STDMETHOD(SetNPatchMode)(
        THIS_ float nSegments);

      STDMETHOD_(float, GetNPatchMode)(
        THIS);

      STDMETHOD(DrawPrimitive)(
        THIS_ D3DPRIMITIVETYPE PrimitiveType,
        UINT StartVertex,
        UINT PrimitiveCount);

      STDMETHOD(DrawIndexedPrimitive)(
        THIS_ D3DPRIMITIVETYPE,
        INT BaseVertexIndex,
        UINT MinVertexIndex,
        UINT NumVertices,
        UINT startIndex,
        UINT primCount);

      STDMETHOD(DrawPrimitiveUP)(
        THIS_ D3DPRIMITIVETYPE PrimitiveType,
        UINT PrimitiveCount,
        CONST void* pVertexStreamZeroData,
        UINT VertexStreamZeroStride);

      STDMETHOD(DrawIndexedPrimitiveUP)(
        THIS_ D3DPRIMITIVETYPE PrimitiveType,
        UINT MinVertexIndex,
        UINT NumVertices,
        UINT PrimitiveCount,
        CONST void* pIndexData,
        D3DFORMAT IndexDataFormat,
        CONST void* pVertexStreamZeroData,
        UINT VertexStreamZeroStride);

      STDMETHOD(ProcessVertices)(
        THIS_ UINT SrcStartIndex,
        UINT DestIndex,
        UINT VertexCount,
        IDirect3DVertexBuffer9* pDestBuffer,
        IDirect3DVertexDeclaration9* pVertexDecl,
        DWORD Flags);

      STDMETHOD(CreateVertexDeclaration)(
        THIS_ CONST D3DVERTEXELEMENT9* pVertexElements,
        IDirect3DVertexDeclaration9** ppDecl);

      STDMETHOD(SetVertexDeclaration)(
        THIS_ IDirect3DVertexDeclaration9* pDecl);

      STDMETHOD(GetVertexDeclaration)(
        THIS_ IDirect3DVertexDeclaration9** ppDecl);

      STDMETHOD(SetFVF)(
        THIS_ DWORD FVF);

      STDMETHOD(GetFVF)(
        THIS_ DWORD* pFVF);

      STDMETHOD(CreateVertexShader)(
        THIS_ CONST DWORD* pFunction,
        IDirect3DVertexShader9** ppShader);

      STDMETHOD(SetVertexShader)(
        THIS_ IDirect3DVertexShader9* pShader);

      STDMETHOD(GetVertexShader)(
        THIS_ IDirect3DVertexShader9** ppShader);

      STDMETHOD(SetVertexShaderConstantF)(
        THIS_ UINT StartRegister,
        CONST float* pConstantData,
        UINT Vector4fCount);

      STDMETHOD(GetVertexShaderConstantF)(
        THIS_ UINT StartRegister,
        float* pConstantData,
        UINT Vector4fCount);

      STDMETHOD(SetVertexShaderConstantI)(
        THIS_ UINT StartRegister,
        CONST int* pConstantData,
        UINT Vector4iCount);

      STDMETHOD(GetVertexShaderConstantI)(
        THIS_ UINT StartRegister,
        int* pConstantData,
        UINT Vector4iCount);

      STDMETHOD(SetVertexShaderConstantB)(
        THIS_ UINT StartRegister,
        CONST BOOL* pConstantData,
        UINT BoolCount);

      STDMETHOD(GetVertexShaderConstantB)(
        THIS_ UINT StartRegister,
        BOOL* pConstantData,
         UINT BoolCount);

      STDMETHOD(SetStreamSource)(
        THIS_ UINT StreamNumber,
        IDirect3DVertexBuffer9* pStreamData,
        UINT OffsetInBytes,
        UINT Stride);

      STDMETHOD(GetStreamSource)(
        THIS_ UINT StreamNumber,
        IDirect3DVertexBuffer9** ppStreamData,
        UINT* pOffsetInBytes,
        UINT* pStride);

      STDMETHOD(SetStreamSourceFreq)(
        THIS_ UINT StreamNumber,
        UINT Setting);

      STDMETHOD(GetStreamSourceFreq)(
        THIS_ UINT StreamNumber,
        UINT* pSetting);

      STDMETHOD(SetIndices)(
        THIS_ IDirect3DIndexBuffer9* pIndexData);

      STDMETHOD(GetIndices)(
        THIS_ IDirect3DIndexBuffer9** ppIndexData);

      STDMETHOD(CreatePixelShader)(
        THIS_ CONST DWORD* pFunction,
        IDirect3DPixelShader9** ppShader);

      STDMETHOD(SetPixelShader)(
        THIS_ IDirect3DPixelShader9* pShader);

      STDMETHOD(GetPixelShader)(
        THIS_ IDirect3DPixelShader9** ppShader);

      STDMETHOD(SetPixelShaderConstantF)(
        THIS_ UINT StartRegister,
        CONST float* pConstantData,
        UINT Vector4fCount);

      STDMETHOD(GetPixelShaderConstantF)(
        THIS_ UINT StartRegister,
        float* pConstantData,
        UINT Vector4fCount);

      STDMETHOD(SetPixelShaderConstantI)(
        THIS_ UINT StartRegister,
        CONST int* pConstantData,
        UINT Vector4iCount);

      STDMETHOD(GetPixelShaderConstantI)(
        THIS_ UINT StartRegister,
        int* pConstantData,
        UINT Vector4iCount);

      STDMETHOD(SetPixelShaderConstantB)(
        THIS_ UINT StartRegister,
        CONST BOOL* pConstantData,
        UINT  BoolCount);

      STDMETHOD(GetPixelShaderConstantB)(
        THIS_ UINT StartRegister,
        BOOL* pConstantData,
        UINT BoolCount);

      STDMETHOD(DrawRectPatch)(
        THIS_ UINT Handle,
        CONST float* pNumSegs,
        CONST D3DRECTPATCH_INFO* pRectPatchInfo);

      STDMETHOD(DrawTriPatch)(
        THIS_ UINT Handle,
        CONST float* pNumSegs,
        CONST D3DTRIPATCH_INFO* pTriPatchInfo);

      STDMETHOD(DeletePatch)(
        THIS_ UINT Handle);

      STDMETHOD(CreateQuery)(
        THIS_ D3DQUERYTYPE Type,
        IDirect3DQuery9** ppQuery);

    private:
      IDirect3D9* m_pD3D;
      IDirect3DDevice9* m_pDevice;
      D3DPRESENT_PARAMETERS m_PresentParams;
      UINT m_RefCount;

      std::shared_ptr<GUI::D3D9Renderer> m_pRenderer;
    };
  }
}
  <|endoftext|>


<commit_before>#include "review.h"
#include "reviews.h"
#include "helper.h"

// Boost.Test does not play well with -Weffc++
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <boost/test/unit_test.hpp>

using namespace kdr;

BOOST_AUTO_TEST_CASE(test_get_review)
{
  const auto rs = get_reviews();
  BOOST_REQUIRE(!rs.empty());
  const review r = rs.back();
  BOOST_CHECK(!r.get_grades().empty());

}

BOOST_AUTO_TEST_CASE(test_is_meta_review)
{
  const std::string md_filename{
    get_default_folder_name() + std::string("/AnalysisRichel.md")
  };
  BOOST_CHECK(is_meta_review(md_filename));
}

BOOST_AUTO_TEST_CASE(test_Richels_analysis_is_not_a_review)
{
  const std::string md_filename{
    get_default_folder_name() + std::string("/AnalysisRichel.md")
  };
  BOOST_REQUIRE(is_regular_file(md_filename));
  BOOST_CHECK_THROW(
    review r(md_filename),
    std::invalid_argument
  );

}

#pragma GCC diagnostic pop

<commit_msg>Detect and display ungraded reviews<commit_after>#include "review.h"
#include "reviews.h"
#include "helper.h"

// Boost.Test does not play well with -Weffc++
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <boost/test/unit_test.hpp>

using namespace kdr;

BOOST_AUTO_TEST_CASE(test_review_must_have_grades)
{
  const auto rs = get_reviews();
  for (const auto r: rs)
  {
    if (r.get_grades().empty())
    {
      std::cerr << "Ungraded review: " << r.get_title() << '\n';
    }
    BOOST_CHECK(!r.get_grades().empty());
  }
}

BOOST_AUTO_TEST_CASE(test_is_meta_review)
{
  const std::string md_filename{
    get_default_folder_name() + std::string("/AnalysisRichel.md")
  };
  BOOST_CHECK(is_meta_review(md_filename));
}

BOOST_AUTO_TEST_CASE(test_Richels_analysis_is_not_a_review)
{
  const std::string md_filename{
    get_default_folder_name() + std::string("/AnalysisRichel.md")
  };
  BOOST_REQUIRE(is_regular_file(md_filename));
  BOOST_CHECK_THROW(
    review r(md_filename),
    std::invalid_argument
  );

}

#pragma GCC diagnostic pop

<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "SurgSim/Math/SegmentMeshShape.h"

#include "SurgSim/DataStructures/AabbTree.h"
#include "SurgSim/DataStructures/AabbTreeData.h"
#include "SurgSim/Framework/Log.h"
#include "SurgSim/Math/Geometry.h"

namespace SurgSim
{
namespace Math
{
SURGSIM_REGISTER(SurgSim::Math::Shape, SurgSim::Math::SegmentMeshShape, SegmentMeshShape);

SegmentMeshShape::SegmentMeshShape()
{
	setRadius(0.0);
	updateAabbTree();
}

SegmentMeshShape::SegmentMeshShape(const SegmentMeshShape& other) :
	DataStructures::SegmentMeshPlain(other)
{
	setRadius(other.m_radius);
	updateAabbTree();
}

int SegmentMeshShape::getType() const
{
	return SHAPE_TYPE_SEGMENTMESH;
}

double SegmentMeshShape::getVolume() const
{
	SURGSIM_ASSERT("SegmentMeshShape: Volume calculation not implemented.");
	return std::numeric_limits<double>::quiet_NaN();
}

Vector3d SegmentMeshShape::getCenter() const
{
	SURGSIM_ASSERT("SegmentMeshShape: Center calculation not implemented.");
	return Vector3d::Constant(std::numeric_limits<double>::quiet_NaN());
}

Matrix33d SegmentMeshShape::getSecondMomentOfVolume() const
{
	SURGSIM_ASSERT("SegmentMeshShape: Second Moment Of Volume calculation not implemented.");
	return Matrix33d::Constant(std::numeric_limits<double>::quiet_NaN());
}

bool SegmentMeshShape::isValid() const
{
	// If the radius is less than DistanceEpsilon, the collision detection (which assumes the segments are capsules),
	/// will not work correctly.
	return (m_radius >= Geometry::DistanceEpsilon &&
			m_segmentEndBoundingBoxHalfExtent.isApprox(Vector3d(m_radius, m_radius, m_radius)));
}

void SegmentMeshShape::setRadius(double radius)
{
	m_radius = radius;
	m_segmentEndBoundingBoxHalfExtent = Vector3d(m_radius, m_radius, m_radius);
}

double SegmentMeshShape::getRadius() const
{
	return m_radius;
}

bool SegmentMeshShape::doUpdate()
{
	updateAabbTree();
	return true;
}

bool SegmentMeshShape::doLoad(const std::string& fileName)
{
	return DataStructures::SegmentMeshPlain::doLoad(fileName) && update();
}

std::shared_ptr<const DataStructures::AabbTree> SegmentMeshShape::getAabbTree() const
{
	return m_aabbTree;
}

std::shared_ptr<Shape> SegmentMeshShape::getTransformed(const RigidTransform3d& pose)
{
	auto transformed = std::make_shared<SegmentMeshShape>(*this);
	transformed->transform(pose);
	transformed->update();
	return transformed;
}

void SegmentMeshShape::updateAabbTree()
{
	m_aabbTree = std::make_shared<DataStructures::AabbTree>();

	std::list<DataStructures::AabbTreeData::Item> items;

	auto const& edges = getEdges();

	for (size_t id = 0, count = edges.size(); id < count; ++id)
	{
		if (edges[id].isValid)
		{
			const auto& vertices = getEdgePositions(id);
			Aabbd aabb((vertices[0] - m_segmentEndBoundingBoxHalfExtent).eval());
			aabb.extend((vertices[0] + m_segmentEndBoundingBoxHalfExtent).eval());
			aabb.extend((vertices[1] - m_segmentEndBoundingBoxHalfExtent).eval());
			aabb.extend((vertices[1] + m_segmentEndBoundingBoxHalfExtent).eval());
			items.emplace_back(std::make_pair(std::move(aabb), id));
		}
	}
	m_aabbTree->set(std::move(items));
}

bool SegmentMeshShape::isTransformable() const
{
	return true;
}

}; // namespace Math
}; // namespace SurgSim
<commit_msg>Give SegmentMeshShape a default radius<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "SurgSim/Math/SegmentMeshShape.h"

#include "SurgSim/DataStructures/AabbTree.h"
#include "SurgSim/DataStructures/AabbTreeData.h"
#include "SurgSim/Framework/Log.h"
#include "SurgSim/Math/Geometry.h"

namespace SurgSim
{
namespace Math
{
SURGSIM_REGISTER(SurgSim::Math::Shape, SurgSim::Math::SegmentMeshShape, SegmentMeshShape);

SegmentMeshShape::SegmentMeshShape()
{
	setRadius(0.001);
	updateAabbTree();
}

SegmentMeshShape::SegmentMeshShape(const SegmentMeshShape& other) :
	DataStructures::SegmentMeshPlain(other)
{
	setRadius(other.m_radius);
	updateAabbTree();
}

int SegmentMeshShape::getType() const
{
	return SHAPE_TYPE_SEGMENTMESH;
}

double SegmentMeshShape::getVolume() const
{
	SURGSIM_ASSERT("SegmentMeshShape: Volume calculation not implemented.");
	return std::numeric_limits<double>::quiet_NaN();
}

Vector3d SegmentMeshShape::getCenter() const
{
	SURGSIM_ASSERT("SegmentMeshShape: Center calculation not implemented.");
	return Vector3d::Constant(std::numeric_limits<double>::quiet_NaN());
}

Matrix33d SegmentMeshShape::getSecondMomentOfVolume() const
{
	SURGSIM_ASSERT("SegmentMeshShape: Second Moment Of Volume calculation not implemented.");
	return Matrix33d::Constant(std::numeric_limits<double>::quiet_NaN());
}

bool SegmentMeshShape::isValid() const
{
	// If the radius is less than DistanceEpsilon, the collision detection (which assumes the segments are capsules),
	/// will not work correctly.
	return (m_radius >= Geometry::DistanceEpsilon &&
			m_segmentEndBoundingBoxHalfExtent.isApprox(Vector3d(m_radius, m_radius, m_radius)));
}

void SegmentMeshShape::setRadius(double radius)
{
	m_radius = radius;
	m_segmentEndBoundingBoxHalfExtent = Vector3d(m_radius, m_radius, m_radius);
}

double SegmentMeshShape::getRadius() const
{
	return m_radius;
}

bool SegmentMeshShape::doUpdate()
{
	updateAabbTree();
	return true;
}

bool SegmentMeshShape::doLoad(const std::string& fileName)
{
	return DataStructures::SegmentMeshPlain::doLoad(fileName) && update();
}

std::shared_ptr<const DataStructures::AabbTree> SegmentMeshShape::getAabbTree() const
{
	return m_aabbTree;
}

std::shared_ptr<Shape> SegmentMeshShape::getTransformed(const RigidTransform3d& pose)
{
	auto transformed = std::make_shared<SegmentMeshShape>(*this);
	transformed->transform(pose);
	transformed->update();
	return transformed;
}

void SegmentMeshShape::updateAabbTree()
{
	m_aabbTree = std::make_shared<DataStructures::AabbTree>();

	std::list<DataStructures::AabbTreeData::Item> items;

	auto const& edges = getEdges();

	for (size_t id = 0; id < edges.size(); ++id)
	{
		if (edges[id].isValid)
		{
			const auto& vertices = getEdgePositions(id);
			Aabbd aabb((vertices[0] - m_segmentEndBoundingBoxHalfExtent).eval());
			aabb.extend((vertices[0] + m_segmentEndBoundingBoxHalfExtent).eval());
			aabb.extend((vertices[1] - m_segmentEndBoundingBoxHalfExtent).eval());
			aabb.extend((vertices[1] + m_segmentEndBoundingBoxHalfExtent).eval());
			items.emplace_back(aabb, id);
		}
	}
	m_aabbTree->set(std::move(items));
}

bool SegmentMeshShape::isTransformable() const
{
	return true;
}

}; // namespace Math
}; // namespace SurgSim
<|endoftext|>


<commit_before>#include "ghost/config.h"
#include "ghost/types.h"
#include "ghost/densemat.h"
#include "ghost/util.h"
#include "ghost/math.h"
#include "ghost/tsmttsm.h"
#include "ghost/tsmttsm_gen.h"
#include "ghost/tsmttsm_avx_gen.h"

#include <map>

using namespace std;

static bool operator<(const ghost_tsmttsm_parameters_t &a, const ghost_tsmttsm_parameters_t &b)
{
    return ghost_hash(a.dt,a.wcols,ghost_hash(a.vcols,a.impl,ghost_hash(a.xstor,a.wstor,0))) < ghost_hash(b.dt,b.wcols,ghost_hash(b.vcols,b.impl,ghost_hash(b.xstor,b.wstor,0)));
}

static map<ghost_tsmttsm_parameters_t, ghost_tsmttsm_kernel_t> ghost_tsmttsm_kernels;

ghost_error_t ghost_tsmttsm_valid(ghost_densemat_t *x, ghost_densemat_t *v, const char * transv,
ghost_densemat_t *w, const char *transw, void *alpha, void *beta, int reduce, int printerror)
{
    if (w->traits.storage != GHOST_DENSEMAT_ROWMAJOR) {
        if (printerror) {
            ERROR_LOG("w must be stored row-major!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (v->traits.storage != GHOST_DENSEMAT_ROWMAJOR) {
        if (printerror) {
            ERROR_LOG("v must be stored row-major!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (x->traits.storage != GHOST_DENSEMAT_COLMAJOR) {
        if (printerror) {
            ERROR_LOG("x must be stored col-major!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (v->traits.datatype != w->traits.datatype || v->traits.datatype != x->traits.datatype) {
        if (printerror) {
            ERROR_LOG("Different data types!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (v->traits.flags & GHOST_DENSEMAT_SCATTERED || w->traits.flags & GHOST_DENSEMAT_SCATTERED || x->traits.flags & GHOST_DENSEMAT_SCATTERED) {
        if (printerror) {
            ERROR_LOG("Scattered densemats not supported!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (reduce != GHOST_GEMM_ALL_REDUCE) {
        if (printerror) {
            ERROR_LOG("Only Allreduce supported currently!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (!strncasecmp(transv,"N",1)) {
        if (printerror) {
            ERROR_LOG("v must be transposed!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (strncasecmp(transw,"N",1)) {
        if (printerror) {
            ERROR_LOG("w must not be transposed!");
        }
        return GHOST_ERR_INVALID_ARG;
    }

    UNUSED(alpha);
    UNUSED(beta);

    return GHOST_SUCCESS;
}

ghost_error_t ghost_tsmttsm(ghost_densemat_t *x, ghost_densemat_t *v, ghost_densemat_t *w, void *alpha, void *beta,int reduce,int conjv)
{
    GHOST_FUNC_ENTER(GHOST_FUNCTYPE_MATH);
    ghost_error_t ret;

    if ((ret = ghost_tsmttsm_valid(x,v,"T",w,"N",alpha,beta,reduce,1)) != GHOST_SUCCESS) {
        return ret;
    }

    if (ghost_tsmttsm_kernels.empty()) {
#include "tsmttsm.def"
#include "tsmttsm_avx.def"
    }

    ghost_tsmttsm_parameters_t p;
    ghost_tsmttsm_kernel_t kernel = NULL;

#ifdef GHOST_HAVE_MIC
    p.impl = GHOST_IMPLEMENTATION_MIC;
#elif defined(GHOST_HAVE_AVX)
    p.impl = GHOST_IMPLEMENTATION_AVX;
#elif defined(GHOST_HAVE_SSE)
    p.impl = GHOST_IMPLEMENTATION_SSE;
#else
    p.impl = GHOST_IMPLEMENTATION_PLAIN;
#endif

    /*if (x->traits.ncolspadded < 4 || x->traits.flags & GHOST_DENSEMAT_VIEW) {
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
    }*/
    //p.impl = GHOST_IMPLEMENTATION_PLAIN;

    p.dt = x->traits.datatype;

    p.vcols = v->traits.ncols;
    p.wcols = w->traits.ncols;

    if (p.vcols % 4 || p.wcols % 4) {
        PERFWARNING_LOG("Use plain for non-multiple of four");
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
    }

    kernel = ghost_tsmttsm_kernels[p];

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary wcols");
        p.wcols = -1;
        p.vcols = v->traits.ncols;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary vcols");
        p.wcols = w->traits.ncols;
        p.vcols = -1;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary block sizes");
        p.wcols = -1;
        p.vcols = -1;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try plain implementation");
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
        p.vcols = v->traits.ncols;
        p.wcols = w->traits.ncols;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary wcols");
        p.wcols = -1;
        p.vcols = v->traits.ncols;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary vcols");
        p.wcols = w->traits.ncols;
        p.vcols = -1;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary block sizes");
        p.wcols = -1;
        p.vcols = -1;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        INFO_LOG("Could not find TSMTTSM kernel with %d %d %d. Fallback to GEMM",p.dt,p.wcols,p.vcols);
        return GHOST_ERR_INVALID_ARG;

            //return ghost_gemm(x,v,"T",w,"N",alpha,beta,GHOST_GEMM_ALL_REDUCE,GHOST_GEMM_NOT_SPECIAL);
    }

    ret = kernel(x,v,w,alpha,beta,conjv);

#ifdef GHOST_HAVE_INSTR_TIMING
    ghost_gemm_perf_args_t tsmttsm_perfargs;
    tsmttsm_perfargs.xcols = p.wcols;
    tsmttsm_perfargs.vcols = p.vcols;
    if (v->context) {
        tsmttsm_perfargs.vrows = v->context->gnrows;
    } else {
        tsmttsm_perfargs.vrows = v->traits.nrows;
    }
    tsmttsm_perfargs.dt = x->traits.datatype;
    ghost_timing_set_perfFunc(__ghost_functag,ghost_gemm_perf_GFs,(void *)&tsmttsm_perfargs,sizeof(tsmttsm_perfargs),"GF/s");
#endif

    GHOST_FUNC_EXIT(GHOST_FUNCTYPE_MATH);

    return ret;
}

<commit_msg>be more verbose<commit_after>#include "ghost/config.h"
#include "ghost/types.h"
#include "ghost/densemat.h"
#include "ghost/util.h"
#include "ghost/math.h"
#include "ghost/tsmttsm.h"
#include "ghost/tsmttsm_gen.h"
#include "ghost/tsmttsm_avx_gen.h"

#include <map>

using namespace std;

static bool operator<(const ghost_tsmttsm_parameters_t &a, const ghost_tsmttsm_parameters_t &b)
{
    return ghost_hash(a.dt,a.wcols,ghost_hash(a.vcols,a.impl,ghost_hash(a.xstor,a.wstor,0))) < ghost_hash(b.dt,b.wcols,ghost_hash(b.vcols,b.impl,ghost_hash(b.xstor,b.wstor,0)));
}

static map<ghost_tsmttsm_parameters_t, ghost_tsmttsm_kernel_t> ghost_tsmttsm_kernels;

ghost_error_t ghost_tsmttsm_valid(ghost_densemat_t *x, ghost_densemat_t *v, const char * transv,
ghost_densemat_t *w, const char *transw, void *alpha, void *beta, int reduce, int printerror)
{
    if (w->traits.storage != GHOST_DENSEMAT_ROWMAJOR) {
        if (printerror) {
            ERROR_LOG("w must be stored row-major!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (v->traits.storage != GHOST_DENSEMAT_ROWMAJOR) {
        if (printerror) {
            ERROR_LOG("v must be stored row-major!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (x->traits.storage != GHOST_DENSEMAT_COLMAJOR) {
        if (printerror) {
            ERROR_LOG("x must be stored col-major!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (v->traits.datatype != w->traits.datatype || v->traits.datatype != x->traits.datatype) {
        if (printerror) {
            ERROR_LOG("Different data types!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (v->traits.flags & GHOST_DENSEMAT_SCATTERED || w->traits.flags & GHOST_DENSEMAT_SCATTERED || x->traits.flags & GHOST_DENSEMAT_SCATTERED) {
        if (printerror) {
            ERROR_LOG("Scattered densemats not supported!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (reduce != GHOST_GEMM_ALL_REDUCE) {
        if (printerror) {
            ERROR_LOG("Only Allreduce supported currently!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (!strncasecmp(transv,"N",1)) {
        if (printerror) {
            ERROR_LOG("v must be transposed!");
        }
        return GHOST_ERR_INVALID_ARG;
    }
    if (strncasecmp(transw,"N",1)) {
        if (printerror) {
            ERROR_LOG("w must not be transposed!");
        }
        return GHOST_ERR_INVALID_ARG;
    }

    UNUSED(alpha);
    UNUSED(beta);

    return GHOST_SUCCESS;
}

ghost_error_t ghost_tsmttsm(ghost_densemat_t *x, ghost_densemat_t *v, ghost_densemat_t *w, void *alpha, void *beta,int reduce,int conjv)
{
    GHOST_FUNC_ENTER(GHOST_FUNCTYPE_MATH);
    ghost_error_t ret;

    if ((ret = ghost_tsmttsm_valid(x,v,"T",w,"N",alpha,beta,reduce,1)) != GHOST_SUCCESS) {
        return ret;
    }

    if (ghost_tsmttsm_kernels.empty()) {
#include "tsmttsm.def"
#include "tsmttsm_avx.def"
    }

    ghost_tsmttsm_parameters_t p;
    ghost_tsmttsm_kernel_t kernel = NULL;

#ifdef GHOST_HAVE_MIC
    p.impl = GHOST_IMPLEMENTATION_MIC;
#elif defined(GHOST_HAVE_AVX)
    p.impl = GHOST_IMPLEMENTATION_AVX;
#elif defined(GHOST_HAVE_SSE)
    p.impl = GHOST_IMPLEMENTATION_SSE;
#else
    p.impl = GHOST_IMPLEMENTATION_PLAIN;
#endif

    /*if (x->traits.ncolspadded < 4 || x->traits.flags & GHOST_DENSEMAT_VIEW) {
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
    }*/
    //p.impl = GHOST_IMPLEMENTATION_PLAIN;

    p.dt = x->traits.datatype;

    p.vcols = v->traits.ncols;
    p.wcols = w->traits.ncols;

    if (p.vcols % 4 || p.wcols % 4) {
        PERFWARNING_LOG("Use plain for non-multiple of four");
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
    }

    kernel = ghost_tsmttsm_kernels[p];

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary wcols");
        p.wcols = -1;
        p.vcols = v->traits.ncols;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary vcols");
        p.wcols = w->traits.ncols;
        p.vcols = -1;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary block sizes");
        p.wcols = -1;
        p.vcols = -1;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try plain implementation");
        p.impl = GHOST_IMPLEMENTATION_PLAIN;
        p.vcols = v->traits.ncols;
        p.wcols = w->traits.ncols;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary wcols");
        p.wcols = -1;
        p.vcols = v->traits.ncols;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary vcols");
        p.wcols = w->traits.ncols;
        p.vcols = -1;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        PERFWARNING_LOG("Try kernel with arbitrary block sizes");
        p.wcols = -1;
        p.vcols = -1;
        kernel = ghost_tsmttsm_kernels[p];
    }

    if (!kernel) {
        INFO_LOG("Could not find TSMTTSM kernel with %d %d %d %d %d. Fallback to GEMM",p.dt,p.wcols,p.vcols,p.xstor,p.wstor);
        return GHOST_ERR_INVALID_ARG;

            //return ghost_gemm(x,v,"T",w,"N",alpha,beta,GHOST_GEMM_ALL_REDUCE,GHOST_GEMM_NOT_SPECIAL);
    }

    ret = kernel(x,v,w,alpha,beta,conjv);

#ifdef GHOST_HAVE_INSTR_TIMING
    ghost_gemm_perf_args_t tsmttsm_perfargs;
    tsmttsm_perfargs.xcols = p.wcols;
    tsmttsm_perfargs.vcols = p.vcols;
    if (v->context) {
        tsmttsm_perfargs.vrows = v->context->gnrows;
    } else {
        tsmttsm_perfargs.vrows = v->traits.nrows;
    }
    tsmttsm_perfargs.dt = x->traits.datatype;
    ghost_timing_set_perfFunc(__ghost_functag,ghost_gemm_perf_GFs,(void *)&tsmttsm_perfargs,sizeof(tsmttsm_perfargs),"GF/s");
#endif

    GHOST_FUNC_EXIT(GHOST_FUNCTYPE_MATH);

    return ret;
}

<|endoftext|>


<commit_before>#include "twister.h"

const unsigned CYCLE = 0x100;

//Suggest we wrap these arrays inside an fsm or test base class
const unsigned C_TRANS_ = 0xff;
int block_units[][0x10] = {
	0x74, 0x63, 0x69, 0x67, 0x72, 0x68, 0x6e, 0x6c, 0x61, 0x67, 0x74, 0x6c, 0x69, 0x73, 0x61, 0x61, 0x6f, 0x6d, 0x6f, 0x72, 0x6e, 0x72, 0x69, 0x6d, 0x6e, 0x6e, 0x65, 0x74, 0x72, 0x6e, 0x6b, 0x73, 0x61, 0x6f, 0x65, 0x69, 0x73, 0x64, 0x6c, 0x65, 0x69, 0x6b, 0x68, 0x68, 0x68, 0x65, 0x72, 0x64, 0x66, 0x74, 0x61, 0x73, 0x6f, 0x69, 0x65, 0x74, 0x69, 0x68, 0x6e, 0x65, 0x62, 0x74, 0x6b, 0x65
  };
int triad_units[][0x03] = {
	0x31, 0xfe, 0x45, 0x74, 0x68, 0x65, 0x74, 0x68, 0x61, 0x65, 0x74, 0x68, 0x66, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x68, 0x61, 0x74, 0x68, 0x69, 0x73, 0x1a, 0x36, 0x49, 0x91, 0x43, 0x53, 0xa9, 0xc3, 0x08, 0xaf, 0x08, 0xf0
};
const int transition_seq[] = { 0xce, 0xab, 0xdf, 0xcf, 0xee,
                               0xcf, 0xad, 0xdf, 0xff, 0xce,
                               0x32, 0x40, 0xd3, 0x27, 0x82,
                               0xda, 0xee, 0xff, 0xfc, 0xbf,
                               0x1c, 0x90, 0x13, 0x4a, 0xa5,
                               0xe0, 0x21, 0x9f, 0xe1, 0xc6,
                               0xaf, 0x05, 0x81, 0xf0, 0xee,
                               0xe4, 0x38, 0x1f, 0x60, 0x24,
                               0x0c, 0x35, 0x51, 0x32, 0xcf,
                               0x12, 0x9a, 0x30, 0x44, 0x72,
                               0x51, 0x3c, 0x61, 0x2d, 0x5f,
                               0x04, 0x1c, 0x52, 0xca, 0xdf,
                               0x12, 0x0b, 0x30, 0xa0, 0x1e,
                               0x03, 0x14, 0x09, 0x73, 0x23,
                               0xf2, 0xca, 0xa2, 0x51, 0xc6,
                               0x01, 0xdf, 0x41, 0x96, 0xa0,
                               0x51, 0x19, 0x71, 0x23, 0x47,
                               0xcb, 0xbd, 0xba, 0xac, 0xdf,
			       0xdf, 0xde, 0xcd, 0xfd, 0xca };

int ENTRY_LINK__ = 0x05;
int ENTRY_LINK__TEST = 0x09;
int ENTRY_C_REF_ECM = 0x10;
int ENTRY_C_REF_ECM_TEST = 0x03;
int ENTRY_C_OUTER = 0x51;
int ENTRY_C_OUTER_PROD = 0x41;
int ENTRY_C_OUTER_PROD_TEST = 0x33;
int ENTRY_C_OUTER_PROD_TOR_TEST = 0x57;
int ENTRY_A_OUTER_PROD_TOR_TEST = 0xc9;
int ENTRY_B_OUTER_PROD_EUC_TEST = 0xaf;
int ENTRY_C_OUTER_PROD_EUC_TEST = 0xa1;
int ENTRY_C_INNER_PROD_EUC_TEST = 0xc5;
int ENTRY_C_INNER_PROD_ELIP_TEST = 0xa2;
int ENTRY_C_INNER_PROD_RELAY_TEST = 0xf5;
int ENTRY_C_BLOCK_REL_FLAG_TEST = 0x0fffffff;
int ENTRY_C_BLOCK_REL_FLAG_VECTOR = 0x0effffff;

unsigned reflect(unsigned center, unsigned (*r)(unsigned))
{
  return (*r)(center)^center;
}
unsigned char base(unsigned char a, unsigned char (*s)(unsigned char), int pos)
{
	return (*s)(pos)^a;
}

void transHomExt(vector<unsigned char>& data, unsigned char (*f)(unsigned char), unsigned char (*g)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d)^base(d, g, d);
    }
    data[i] = d;
  }
}
void transHom(vector<unsigned char>& data, unsigned char (*f)(unsigned char), unsigned char (*g)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d)^(*g)(d);
    }
    data[i] = d;
  }
}

void trans(vector<unsigned char>& data, unsigned char (*f)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d);
    }
    data[i] = d;
  }
}

vector<double> f_dist(vector<unsigned char>& in)
{
  vector<double> fdist;
  fdist.resize(256);
  for(unsigned i = 0; i<in.size(); i++)
  {
    fdist[in[i]]++;
  }

  for(unsigned i=0; i<fdist.size(); i++)
  {
    fdist[i] = (fdist[i] / in.size()) * 100;
  }

  return fdist;
}

double s_entropy(vector<double>& v)
{
  double entropy = 0;
  double p;

  for(unsigned i = 0; i < v.size(); i++)
  {
    p = v[i] / 100;
    if (p == 0) continue;
    entropy += p * std::log(p) / std::log(2);
  }
  return -entropy;
}
void rms(const string& s, string& r)
{
  for(unsigned int i=0; i<s.size(); i++)
  {
    if(::isspace(s[i])) continue;
    r+= s[i];
  }
}
//add extended euc
double sw(double weight, int i, int j, int (*inv)(int, int))
{
  return weight*(*inv)(i, j);
}
//Suggest we wrap these routines in a base class in particular for testing
//and expose test api
void hPerm(int s, int n, void (*p)(int), void (*inv)(int, int), void (*center)(int))
{
  if(transition_seq[ENTRY_C_INNER_PROD_RELAY_TEST] == s)
  {
	  (*center)(s);
	  return;
  }
  if(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST ] == s)
  {
	  (*p)(s);
	  return;
  }
  if(s == 1)
  {
    (*p)(n);
    return;
  }
  for(int i=0; i< s; i++)
  {
    hPerm(s-1, n, p, inv, p);
    if(s%2 == 1)
      (*inv)(0, s-1);
    else
      (*inv)(i, s-1);
  }
}

double ic(const string& t)
{
  string text; rms(t, text);
  vector<double> freq(256,0);
  for(unsigned int i=0; i<text.size(); i++)
  {
    if(text[i] == ' ') continue;
    freq[text[i]] ++;
  }
  double sum=0;
  for(unsigned int i=0; i<freq.size(); i++)
  {
    if(freq[i] != 0)
    {
      double c = freq[i];
      if(c != 0)
        sum += c * (c - 1);
    }
  }
  double ic = 26 * sum / (text.size() * (text.size() - 1));
  return ic;
}

int outer_sect(int (*s)(int), int (*t)(int), int r, int q)
{
  return (*s)(r) * (*t)(q);
}

void multiChan(unsigned char* (*p)(unsigned char, unsigned char), unsigned char m)
{
  unsigned char* chanIndicator = (*p)(transition_seq[ENTRY_C_REF_ECM], m);
  unsigned char* crossCh = (*p)(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST], m);
  *chanIndicator = *chanIndicator ^ *crossCh;
  *crossCh = *chanIndicator ^ *crossCh;
  *chanIndicator = *chanIndicator ^ *crossCh;

}

void switchIO(unsigned char (*p)(unsigned char, unsigned char), unsigned char m)
{
  //test seq
  (*p)(transition_seq[ENTRY_LINK__], m);
  (*p)(transition_seq[ENTRY_LINK__TEST], m);
  //stream test , suggest these tests should be moved to a state transition class
  //
  //
  //
  (*p)(transition_seq[ENTRY_C_REF_ECM], m ^ 0xff );
  (*p)(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST  ], m);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_LINK__TEST]);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_C_REF_ECM]);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST]);

}

//Suggest we wrap these in util base class, abstract col cont
std::tuple<int, int, int> extended_gcd(int __alpha, int __beta, int (*col)(int x, int y))
{
  if(__alpha == 0) return make_tuple(__beta,0,1);
  int __com=0;
  int x=0;
  int y=0;
  tie(__com, x, y) = extended_gcd(__beta%__alpha, __alpha, col);
  return make_tuple(__com, y-(__beta/__alpha)*x, x);
}
//frmwk wrapper pending nh release, util base
//
std::tuple<int, int, int> extended_gcd(int __alpha, int __beta)
{
  if(__alpha == 0) return make_tuple(__beta,0,1);
  int __com=0;
  int x=0;
  int y=0;
  tie(__com, x, y) = extended_gcd(__beta%__alpha, __alpha);
  return make_tuple(__com, y-(__beta/__alpha)*x, x);
}
<commit_msg>cross ref test tbd<commit_after>#include "twister.h"

const unsigned CYCLE = 0x100;

//Suggest we wrap these arrays inside an fsm or test base class
const unsigned C_TRANS_ = 0xff;
int block_units[][0x10] = {
	0x74, 0x63, 0x69, 0x67, 0x72, 0x68, 0x6e, 0x6c, 0x61, 0x67, 0x74, 0x6c, 0x69, 0x73, 0x61, 0x61, 0x6f, 0x6d, 0x6f, 0x72, 0x6e, 0x72, 0x69, 0x6d, 0x6e, 0x6e, 0x65, 0x74, 0x72, 0x6e, 0x6b, 0x73, 0x61, 0x6f, 0x65, 0x69, 0x73, 0x64, 0x6c, 0x65, 0x69, 0x6b, 0x68, 0x68, 0x68, 0x65, 0x72, 0x64, 0x66, 0x74, 0x61, 0x73, 0x6f, 0x69, 0x65, 0x74, 0x69, 0x68, 0x6e, 0x65, 0x62, 0x74, 0x6b, 0x65
  };
int triad_units[][0x03] = {
	0x31, 0xfe, 0x45, 0x74, 0x68, 0x65, 0x74, 0x68, 0x61, 0x65, 0x74, 0x68, 0x66, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x68, 0x61, 0x74, 0x68, 0x69, 0x73, 0x1a, 0x36, 0x49, 0x91, 0x43, 0x53, 0xa9, 0xc3, 0x08, 0xaf, 0x08, 0xf0
};
const int transition_seq[] = { 0xce, 0xab, 0xdf, 0xcf, 0xee,
                               0xcf, 0xad, 0xdf, 0xff, 0xce,
                               0x32, 0x40, 0xd3, 0x27, 0x82,
                               0xda, 0xee, 0xff, 0xfc, 0xbf,
                               0x1c, 0x90, 0x13, 0x4a, 0xa5,
                               0xe0, 0x21, 0x9f, 0xe1, 0xc6,
                               0xaf, 0x05, 0x81, 0xf0, 0xee,
                               0xe4, 0x38, 0x1f, 0x60, 0x24,
                               0x0c, 0x35, 0x51, 0x32, 0xcf,
                               0x12, 0x9a, 0x30, 0x44, 0x72,
                               0x51, 0x3c, 0x61, 0x2d, 0x5f,
                               0x04, 0x1c, 0x52, 0xca, 0xdf,
                               0x12, 0x0b, 0x30, 0xa0, 0x1e,
                               0x03, 0x14, 0x09, 0x73, 0x23,
                               0xf2, 0xca, 0xa2, 0x51, 0xc6,
                               0x01, 0xdf, 0x41, 0x96, 0xa0,
                               0x51, 0x19, 0x71, 0x23, 0x47,
                               0xcb, 0xbd, 0xba, 0xac, 0xdf,
			       0xdf, 0xde, 0xcd, 0xfd, 0xca };

int ENTRY_LINK__ = 0x05;
int ENTRY_LINK__TEST = 0x09;
int ENTRY_C_REF_ECM = 0x10;
int ENTRY_C_REF_ECM_TEST = 0x03;
int ENTRY_C_OUTER = 0x51;
int ENTRY_C_OUTER_PROD = 0x41;
int ENTRY_C_OUTER_PROD_TEST = 0x33;
int ENTRY_C_OUTER_PROD_TOR_TEST = 0x57;
int ENTRY_A_OUTER_PROD_TOR_TEST = 0xc9;
int ENTRY_B_OUTER_PROD_EUC_TEST = 0xaf;
int ENTRY_C_OUTER_PROD_EUC_TEST = 0xa1;
int ENTRY_C_INNER_PROD_EUC_TEST = 0xc5;
int ENTRY_C_INNER_PROD_ELIP_TEST = 0xa2;
int ENTRY_C_INNER_PROD_RELAY_TEST = 0xf5;
int ENTRY_C_BLOCK_REL_FLAG_TEST = 0x0fffffff;
int ENTRY_C_BLOCK_REL_FLAG_VECTOR = 0x0effffff;

unsigned reflect(unsigned center, unsigned (*r)(unsigned))
{
  return (*r)(center)^center;
}
unsigned char base(unsigned char a, unsigned char (*s)(unsigned char), int pos)
{
	return (*s)(pos)^a;
}

void transHomExt(vector<unsigned char>& data, unsigned char (*f)(unsigned char), unsigned char (*g)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d)^base(d, g, d);
    }
    data[i] = d;
  }
}
void transHom(vector<unsigned char>& data, unsigned char (*f)(unsigned char), unsigned char (*g)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d)^(*g)(d);
    }
    data[i] = d;
  }
}

void trans(vector<unsigned char>& data, unsigned char (*f)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d);
    }
    data[i] = d;
  }
}

vector<double> f_dist(vector<unsigned char>& in)
{
  vector<double> fdist;
  fdist.resize(256);
  for(unsigned i = 0; i<in.size(); i++)
  {
    fdist[in[i]]++;
  }

  for(unsigned i=0; i<fdist.size(); i++)
  {
    fdist[i] = (fdist[i] / in.size()) * 100;
  }

  return fdist;
}

double s_entropy(vector<double>& v)
{
  double entropy = 0;
  double p;

  for(unsigned i = 0; i < v.size(); i++)
  {
    p = v[i] / 100;
    if (p == 0) continue;
    entropy += p * std::log(p) / std::log(2);
  }
  return -entropy;
}
void rms(const string& s, string& r)
{
  for(unsigned int i=0; i<s.size(); i++)
  {
    if(::isspace(s[i])) continue;
    r+= s[i];
  }
}
//add extended euc
double sw(double weight, int i, int j, int (*inv)(int, int))
{
  return weight*(*inv)(i, j);
}
//Suggest we wrap these routines in a base class in particular for testing
//and expose test api
void hPerm(int s, int n, void (*p)(int), void (*inv)(int, int), void (*center)(int))
{
  if(transition_seq[ENTRY_C_INNER_PROD_RELAY_TEST] == s)
  {
	  (*center)(s);
	  return;
  }
  if(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST ] == s)
  {
	  (*p)(s);
	  return;
  }
  if(s == 1)
  {
    (*p)(n);
    return;
  }
  for(int i=0; i< s; i++)
  {
    hPerm(s-1, n, p, inv, p);
    if(s%2 == 1)
      (*inv)(0, s-1);
    else
      (*inv)(i, s-1);
  }
}

double ic(const string& t)
{
  string text; rms(t, text);
  vector<double> freq(256,0);
  for(unsigned int i=0; i<text.size(); i++)
  {
    if(text[i] == ' ') continue;
    freq[text[i]] ++;
  }
  double sum=0;
  for(unsigned int i=0; i<freq.size(); i++)
  {
    if(freq[i] != 0)
    {
      double c = freq[i];
      if(c != 0)
        sum += c * (c - 1);
    }
  }
  double ic = 26 * sum / (text.size() * (text.size() - 1));
  return ic;
}

int outer_sect(int (*s)(int), int (*t)(int), int r, int q)
{
  return (*s)(r) * (*t)(q);
}
//chain cross ref - test -
void multiChan(unsigned char* (*p)(unsigned char, unsigned char), unsigned char m)
{
  unsigned char* chanIndicator = (*p)(transition_seq[ENTRY_C_REF_ECM], m);
  unsigned char* crossCh = (*p)(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST], m);
  *chanIndicator = *chanIndicator ^ *crossCh;
  *crossCh = *chanIndicator ^ *crossCh;
  *chanIndicator = *chanIndicator ^ *crossCh;

}

void switchIO(unsigned char (*p)(unsigned char, unsigned char), unsigned char m)
{
  //test seq
  (*p)(transition_seq[ENTRY_LINK__], m);
  (*p)(transition_seq[ENTRY_LINK__TEST], m);
  //stream test , suggest these tests should be moved to a state transition class
  //
  //
  //
  (*p)(transition_seq[ENTRY_C_REF_ECM], m ^ 0xff );
  (*p)(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST  ], m);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_LINK__TEST]);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_C_REF_ECM]);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST]);

}

//Suggest we wrap these in util base class, abstract col cont
std::tuple<int, int, int> extended_gcd(int __alpha, int __beta, int (*col)(int x, int y))
{
  if(__alpha == 0) return make_tuple(__beta,0,1);
  int __com=0;
  int x=0;
  int y=0;
  tie(__com, x, y) = extended_gcd(__beta%__alpha, __alpha, col);
  return make_tuple(__com, y-(__beta/__alpha)*x, x);
}
//frmwk wrapper pending nh release, util base
//
std::tuple<int, int, int> extended_gcd(int __alpha, int __beta)
{
  if(__alpha == 0) return make_tuple(__beta,0,1);
  int __com=0;
  int x=0;
  int y=0;
  tie(__com, x, y) = extended_gcd(__beta%__alpha, __alpha);
  return make_tuple(__com, y-(__beta/__alpha)*x, x);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "remoting/host/capturer_gdi.h"
#include "remoting/host/differ.h"

#include "gfx/rect.h"

namespace remoting {

// 3780 pixels per meter is equivalent to 96 DPI, typical on desktop monitors.
static const int kPixelsPerMeter = 3780;
// 32 bit RGBA is 4 bytes per pixel.
static const int kBytesPerPixel = 4;

CapturerGdi::CapturerGdi(MessageLoop* message_loop)
    : Capturer(message_loop),
      desktop_dc_(NULL),
      memory_dc_(NULL),
      capture_fullscreen_(true) {
  memset(target_bitmap_, 0, sizeof(target_bitmap_));
  memset(buffers_, 0, sizeof(buffers_));
}

CapturerGdi::~CapturerGdi() {
  ReleaseBuffers();
}

void CapturerGdi::ReleaseBuffers() {
  for (int i = kNumBuffers - 1; i >= 0; i--) {
    if (target_bitmap_[i]) {
      DeleteObject(target_bitmap_[i]);
      target_bitmap_[i] = NULL;
    }
    if (buffers_[i]) {
      DeleteObject(buffers_[i]);
      buffers_[i] = NULL;
    }
  }

  desktop_dc_ = NULL;
  if (memory_dc_) {
    DeleteDC(memory_dc_);
    memory_dc_ = NULL;
  }
}

void CapturerGdi::ScreenConfigurationChanged() {
  ReleaseBuffers();

  desktop_dc_ = GetDC(GetDesktopWindow());
  memory_dc_ = CreateCompatibleDC(desktop_dc_);

  // Create a bitmap to keep the desktop image.
  width_ = GetSystemMetrics(SM_CXSCREEN);
  height_ = GetSystemMetrics(SM_CYSCREEN);
  int rounded_width = (width_ + 3) & (~3);

  // Dimensions of screen.
  pixel_format_ = media::VideoFrame::RGB32;
  bytes_per_row_ = rounded_width * kBytesPerPixel;

  // Create a differ for this screen size.
  differ_.reset(new Differ(width_, height_, 4, bytes_per_row_));

  // Create a device independant bitmap (DIB) that is the same size.
  BITMAPINFO bmi;
  memset(&bmi, 0, sizeof(bmi));
  bmi.bmiHeader.biHeight = height_;
  bmi.bmiHeader.biWidth = width_;
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = kBytesPerPixel * 8;
  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biSizeImage = bytes_per_row_ * height_;
  bmi.bmiHeader.biXPelsPerMeter = kPixelsPerMeter;
  bmi.bmiHeader.biYPelsPerMeter = kPixelsPerMeter;

  // Create memory for the buffers.
  for (int i = 0; i < kNumBuffers; i++) {
    target_bitmap_[i] = CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS,
                                         static_cast<void**>(&buffers_[i]),
                                         NULL, 0);
  }

  capture_fullscreen_ = true;
}

void CapturerGdi::CalculateInvalidRects() {
  ClearInvalidRects();
  CaptureImage();

  if (capture_fullscreen_) {
    InvalidateFullScreen();
  } else {
    // Calculate the difference between the previous and current screen.
    int prev_buffer_id = current_buffer_ - 1;
    if (prev_buffer_id < 0) {
      prev_buffer_id = kNumBuffers - 1;
    }

    void* prev_buffer = buffers_[prev_buffer_id];
    void* curr_buffer = buffers_[current_buffer_];

    InvalidRects rects;
    differ_->CalcDirtyRects(prev_buffer, curr_buffer, &rects);

    InvalidateRects(rects);
  }

  capture_fullscreen_ = false;
}

void CapturerGdi::CaptureRects(const InvalidRects& rects,
                               CaptureCompletedCallback* callback) {
  DataPlanes planes;
  planes.data[0] = static_cast<uint8*>(buffers_[current_buffer_]);
  planes.strides[0] = bytes_per_row_;

  scoped_refptr<CaptureData> data(new CaptureData(planes,
                                                  width(),
                                                  height(),
                                                  pixel_format()));
  data->mutable_dirty_rects() = rects;

  FinishCapture(data, callback);
}

void CapturerGdi::CaptureImage() {
  // Select the target bitmap into the memory dc.
  SelectObject(memory_dc_, target_bitmap_[current_buffer_]);

  // And then copy the rect from desktop to memory.
  BitBlt(memory_dc_, 0, 0, width_, height_, desktop_dc_, 0, 0,
      SRCCOPY | CAPTUREBLT);
}

}  // namespace remoting
<commit_msg>Fix GDI capturer initialization.<commit_after>// Copyright (c) 2010 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 "remoting/host/capturer_gdi.h"
#include "remoting/host/differ.h"

#include "gfx/rect.h"

namespace remoting {

// 3780 pixels per meter is equivalent to 96 DPI, typical on desktop monitors.
static const int kPixelsPerMeter = 3780;
// 32 bit RGBA is 4 bytes per pixel.
static const int kBytesPerPixel = 4;

CapturerGdi::CapturerGdi(MessageLoop* message_loop)
    : Capturer(message_loop),
      desktop_dc_(NULL),
      memory_dc_(NULL),
      capture_fullscreen_(true) {
  memset(target_bitmap_, 0, sizeof(target_bitmap_));
  memset(buffers_, 0, sizeof(buffers_));
  ScreenConfigurationChanged();
}

CapturerGdi::~CapturerGdi() {
  ReleaseBuffers();
}

void CapturerGdi::ReleaseBuffers() {
  for (int i = kNumBuffers - 1; i >= 0; i--) {
    if (target_bitmap_[i]) {
      DeleteObject(target_bitmap_[i]);
      target_bitmap_[i] = NULL;
    }
    if (buffers_[i]) {
      DeleteObject(buffers_[i]);
      buffers_[i] = NULL;
    }
  }

  desktop_dc_ = NULL;
  if (memory_dc_) {
    DeleteDC(memory_dc_);
    memory_dc_ = NULL;
  }
}

void CapturerGdi::ScreenConfigurationChanged() {
  ReleaseBuffers();

  desktop_dc_ = GetDC(GetDesktopWindow());
  memory_dc_ = CreateCompatibleDC(desktop_dc_);

  // Create a bitmap to keep the desktop image.
  width_ = GetSystemMetrics(SM_CXSCREEN);
  height_ = GetSystemMetrics(SM_CYSCREEN);
  int rounded_width = (width_ + 3) & (~3);

  // Dimensions of screen.
  pixel_format_ = media::VideoFrame::RGB32;
  bytes_per_row_ = rounded_width * kBytesPerPixel;

  // Create a differ for this screen size.
  differ_.reset(new Differ(width_, height_, 4, bytes_per_row_));

  // Create a device independant bitmap (DIB) that is the same size.
  BITMAPINFO bmi;
  memset(&bmi, 0, sizeof(bmi));
  bmi.bmiHeader.biHeight = height_;
  bmi.bmiHeader.biWidth = width_;
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = kBytesPerPixel * 8;
  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biSizeImage = bytes_per_row_ * height_;
  bmi.bmiHeader.biXPelsPerMeter = kPixelsPerMeter;
  bmi.bmiHeader.biYPelsPerMeter = kPixelsPerMeter;

  // Create memory for the buffers.
  for (int i = 0; i < kNumBuffers; i++) {
    target_bitmap_[i] = CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS,
                                         static_cast<void**>(&buffers_[i]),
                                         NULL, 0);
  }

  capture_fullscreen_ = true;
}

void CapturerGdi::CalculateInvalidRects() {
  ClearInvalidRects();
  CaptureImage();

  if (capture_fullscreen_) {
    InvalidateFullScreen();
  } else {
    // Calculate the difference between the previous and current screen.
    int prev_buffer_id = current_buffer_ - 1;
    if (prev_buffer_id < 0) {
      prev_buffer_id = kNumBuffers - 1;
    }

    void* prev_buffer = buffers_[prev_buffer_id];
    void* curr_buffer = buffers_[current_buffer_];

    InvalidRects rects;
    differ_->CalcDirtyRects(prev_buffer, curr_buffer, &rects);

    InvalidateRects(rects);
  }

  capture_fullscreen_ = false;
}

void CapturerGdi::CaptureRects(const InvalidRects& rects,
                               CaptureCompletedCallback* callback) {
  DataPlanes planes;
  planes.data[0] = static_cast<uint8*>(buffers_[current_buffer_]);
  planes.strides[0] = bytes_per_row_;

  scoped_refptr<CaptureData> data(new CaptureData(planes,
                                                  width(),
                                                  height(),
                                                  pixel_format()));
  data->mutable_dirty_rects() = rects;

  FinishCapture(data, callback);
}

void CapturerGdi::CaptureImage() {
  // Select the target bitmap into the memory dc.
  SelectObject(memory_dc_, target_bitmap_[current_buffer_]);

  // And then copy the rect from desktop to memory.
  BitBlt(memory_dc_, 0, 0, width_, height_, desktop_dc_, 0, 0,
      SRCCOPY | CAPTUREBLT);
}

}  // namespace remoting
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "remoting/host/capturer.h"

#include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/CGLMacro.h>
#include <OpenGL/OpenGL.h>

#include <stddef.h>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "remoting/host/capturer_helper.h"

namespace remoting {

namespace {
// A class to perform capturing for mac.
class CapturerMac : public Capturer {
 public:
  CapturerMac();
  virtual ~CapturerMac();

  // Capturer interface.
  virtual void ScreenConfigurationChanged() OVERRIDE;
  virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
  virtual void ClearInvalidRects() OVERRIDE;
  virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE;
  virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE;
  virtual void InvalidateFullScreen() OVERRIDE;
  virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE;
  virtual const gfx::Size& size_most_recent() const OVERRIDE;

 private:
  void CaptureRects(const InvalidRects& rects,
                    CaptureCompletedCallback* callback);

  void ScreenRefresh(CGRectCount count, const CGRect *rect_array);
  void ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
                                size_t count,
                                const CGRect *rect_array);
  static void ScreenRefreshCallback(CGRectCount count,
                                    const CGRect *rect_array,
                                    void *user_parameter);
  static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta,
                                       size_t count,
                                       const CGRect *rect_array,
                                       void *user_parameter);
  static void DisplaysReconfiguredCallback(CGDirectDisplayID display,
                                           CGDisplayChangeSummaryFlags flags,
                                           void *user_parameter);

  void ReleaseBuffers();
  CGLContextObj cgl_context_;
  static const int kNumBuffers = 2;
  scoped_array<uint8> buffers_[kNumBuffers];

  // A thread-safe list of invalid rectangles, and the size of the most
  // recently captured screen.
  CapturerHelper helper_;

  // Screen size.
  int width_;
  int height_;

  int bytes_per_row_;

  // The current buffer with valid data for reading.
  int current_buffer_;

  // Format of pixels returned in buffer.
  media::VideoFrame::Format pixel_format_;

  DISALLOW_COPY_AND_ASSIGN(CapturerMac);
};

CapturerMac::CapturerMac()
    : cgl_context_(NULL),
      width_(0),
      height_(0),
      bytes_per_row_(0),
      current_buffer_(0),
      pixel_format_(media::VideoFrame::RGB32) {
  // TODO(dmaclach): move this initialization out into session_manager,
  // or at least have session_manager call into here to initialize it.
  CGError err =
      CGRegisterScreenRefreshCallback(CapturerMac::ScreenRefreshCallback,
                                      this);
  DCHECK_EQ(err, kCGErrorSuccess);
  err = CGScreenRegisterMoveCallback(CapturerMac::ScreenUpdateMoveCallback,
                                     this);
  DCHECK_EQ(err, kCGErrorSuccess);
  err = CGDisplayRegisterReconfigurationCallback(
      CapturerMac::DisplaysReconfiguredCallback, this);
  DCHECK_EQ(err, kCGErrorSuccess);
  ScreenConfigurationChanged();
  InvalidateScreen(gfx::Size(width_, height_));
}

CapturerMac::~CapturerMac() {
  ReleaseBuffers();
  CGUnregisterScreenRefreshCallback(CapturerMac::ScreenRefreshCallback, this);
  CGScreenUnregisterMoveCallback(CapturerMac::ScreenUpdateMoveCallback, this);
  CGDisplayRemoveReconfigurationCallback(
      CapturerMac::DisplaysReconfiguredCallback, this);
}

void CapturerMac::ReleaseBuffers() {
  if (cgl_context_) {
    CGLDestroyContext(cgl_context_);
    cgl_context_ = NULL;
  }
}

void CapturerMac::ScreenConfigurationChanged() {
  ReleaseBuffers();
  CGDirectDisplayID mainDevice = CGMainDisplayID();

  width_ = CGDisplayPixelsWide(mainDevice);
  height_ = CGDisplayPixelsHigh(mainDevice);
  pixel_format_ = media::VideoFrame::RGB32;
  bytes_per_row_ = width_ * sizeof(uint32_t);
  size_t buffer_size = height_ * bytes_per_row_;
  for (int i = 0; i < kNumBuffers; ++i) {
    buffers_[i].reset(new uint8[buffer_size]);
  }
  CGLPixelFormatAttribute attributes[] = {
    kCGLPFAFullScreen,
    kCGLPFADisplayMask,
    (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice),
    (CGLPixelFormatAttribute)0
  };
  CGLPixelFormatObj pixel_format = NULL;
  GLint matching_pixel_format_count = 0;
  CGLError err = CGLChoosePixelFormat(attributes,
                                      &pixel_format,
                                      &matching_pixel_format_count);
  DCHECK_EQ(err, kCGLNoError);
  err = CGLCreateContext(pixel_format, NULL, &cgl_context_);
  DCHECK_EQ(err, kCGLNoError);
  CGLDestroyPixelFormat(pixel_format);
  CGLSetFullScreen(cgl_context_);
  CGLSetCurrentContext(cgl_context_);
}

media::VideoFrame::Format CapturerMac::pixel_format() const {
  return pixel_format_;
}

void CapturerMac::ClearInvalidRects() {
  helper_.ClearInvalidRects();
}

void CapturerMac::InvalidateRects(const InvalidRects& inval_rects) {
  helper_.InvalidateRects(inval_rects);
}

void CapturerMac::InvalidateScreen(const gfx::Size& size) {
  helper_.InvalidateScreen(size);
}

void CapturerMac::InvalidateFullScreen() {
  helper_.InvalidateFullScreen();
}

void CapturerMac::CaptureInvalidRects(CaptureCompletedCallback* callback) {
  InvalidRects rects;
  helper_.SwapInvalidRects(rects);

  CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
  glReadBuffer(GL_FRONT);
  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);

  glPixelStorei(GL_PACK_ALIGNMENT, 4);  // Force 4-byte alignment.
  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

  // Read a block of pixels from the frame buffer.
  uint8* current_buffer = buffers_[current_buffer_].get();
  glReadPixels(0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE,
               current_buffer);
  glPopClientAttrib();

  DataPlanes planes;
  planes.data[0] = buffers_[current_buffer_].get() + height_ * bytes_per_row_;
  planes.strides[0] = -bytes_per_row_;

  scoped_refptr<CaptureData> data(
      new CaptureData(planes, gfx::Size(width_, height_), pixel_format()));
  data->mutable_dirty_rects() = rects;

  current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
  helper_.set_size_most_recent(data->size());

  callback->Run(data);
  delete callback;
}

const gfx::Size& CapturerMac::size_most_recent() const {
  return helper_.size_most_recent();
}

void CapturerMac::ScreenRefresh(CGRectCount count, const CGRect *rect_array) {
  InvalidRects rects;
  for (CGRectCount i = 0; i < count; ++i) {
    rects.insert(gfx::Rect(rect_array[i]));
  }
  InvalidateRects(rects);
}

void CapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
                                   size_t count,
                                   const CGRect *rect_array) {
  InvalidRects rects;
  for (CGRectCount i = 0; i < count; ++i) {
    CGRect rect = rect_array[i];
    rects.insert(gfx::Rect(rect));
    rect = CGRectOffset(rect, delta.dX, delta.dY);
    rects.insert(gfx::Rect(rect));
  }
  InvalidateRects(rects);
}

void CapturerMac::ScreenRefreshCallback(CGRectCount count,
                                        const CGRect *rect_array,
                                        void *user_parameter) {
  CapturerMac *capturer = reinterpret_cast<CapturerMac *>(user_parameter);
  capturer->ScreenRefresh(count, rect_array);
}

void CapturerMac::ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta,
                                           size_t count,
                                           const CGRect *rect_array,
                                           void *user_parameter) {
  CapturerMac *capturer = reinterpret_cast<CapturerMac *>(user_parameter);
  capturer->ScreenUpdateMove(delta, count, rect_array);
}

void CapturerMac::DisplaysReconfiguredCallback(
    CGDirectDisplayID display,
    CGDisplayChangeSummaryFlags flags,
    void *user_parameter) {
  if ((display == CGMainDisplayID()) &&
      !(flags & kCGDisplayBeginConfigurationFlag)) {
    CapturerMac *capturer = reinterpret_cast<CapturerMac *>(user_parameter);
    capturer->ScreenConfigurationChanged();
  }
}

}  // namespace

// static
Capturer* Capturer::Create() {
  return new CapturerMac();
}

}  // namespace remoting
<commit_msg>Use pixel buffer objects where supported to improve capturer speed.<commit_after>// Copyright (c) 2011 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 "remoting/host/capturer.h"

#include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/CGLMacro.h>
#include <OpenGL/OpenGL.h>

#include <stddef.h>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "remoting/host/capturer_helper.h"

namespace remoting {

namespace {

class scoped_pixel_buffer_object {
 public:
  scoped_pixel_buffer_object();
  ~scoped_pixel_buffer_object();

  bool Init(CGLContextObj cgl_context, int size_in_bytes);
  void Release();

  GLuint get() const { return pixel_buffer_object_; }

 private:
  CGLContextObj cgl_context_;
  GLuint pixel_buffer_object_;

  DISALLOW_COPY_AND_ASSIGN(scoped_pixel_buffer_object);
};

scoped_pixel_buffer_object::scoped_pixel_buffer_object()
    : cgl_context_(NULL),
      pixel_buffer_object_(0) {
}

scoped_pixel_buffer_object::~scoped_pixel_buffer_object() {
  Release();
}

bool scoped_pixel_buffer_object::Init(CGLContextObj cgl_context,
                                      int size_in_bytes) {
  cgl_context_ = cgl_context;
  CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
  glGenBuffersARB(1, &pixel_buffer_object_);
  if (glGetError() == GL_NO_ERROR) {
    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_);
    glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, size_in_bytes, NULL,
                    GL_STREAM_READ_ARB);
    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
    if (glGetError() != GL_NO_ERROR) {
      Release();
    }
  } else {
    cgl_context_ = NULL;
    pixel_buffer_object_ = 0;
  }
  return pixel_buffer_object_ != 0;
}

void scoped_pixel_buffer_object::Release() {
  if (pixel_buffer_object_) {
    CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
    glDeleteBuffersARB(1, &pixel_buffer_object_);
    cgl_context_ = NULL;
    pixel_buffer_object_ = 0;
  }
}

// A class to perform capturing for mac.
class CapturerMac : public Capturer {
 public:
  CapturerMac();
  virtual ~CapturerMac();

  // Capturer interface.
  virtual void ScreenConfigurationChanged() OVERRIDE;
  virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
  virtual void ClearInvalidRects() OVERRIDE;
  virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE;
  virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE;
  virtual void InvalidateFullScreen() OVERRIDE;
  virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE;
  virtual const gfx::Size& size_most_recent() const OVERRIDE;

 private:
  void FastBlit(uint8* buffer);
  void SlowBlit(uint8* buffer);
  void CaptureRects(const InvalidRects& rects,
                    CaptureCompletedCallback* callback);

  void ScreenRefresh(CGRectCount count, const CGRect *rect_array);
  void ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
                                size_t count,
                                const CGRect *rect_array);
  static void ScreenRefreshCallback(CGRectCount count,
                                    const CGRect *rect_array,
                                    void *user_parameter);
  static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta,
                                       size_t count,
                                       const CGRect *rect_array,
                                       void *user_parameter);
  static void DisplaysReconfiguredCallback(CGDirectDisplayID display,
                                           CGDisplayChangeSummaryFlags flags,
                                           void *user_parameter);

  void ReleaseBuffers();
  CGLContextObj cgl_context_;
  static const int kNumBuffers = 2;
  scoped_pixel_buffer_object pixel_buffer_object_;
  scoped_array<uint8> buffers_[kNumBuffers];

  // A thread-safe list of invalid rectangles, and the size of the most
  // recently captured screen.
  CapturerHelper helper_;

  // Screen size.
  int width_;
  int height_;

  int bytes_per_row_;

  // The current buffer with valid data for reading.
  int current_buffer_;

  // Format of pixels returned in buffer.
  media::VideoFrame::Format pixel_format_;

  DISALLOW_COPY_AND_ASSIGN(CapturerMac);
};

CapturerMac::CapturerMac()
    : cgl_context_(NULL),
      width_(0),
      height_(0),
      bytes_per_row_(0),
      current_buffer_(0),
      pixel_format_(media::VideoFrame::RGB32) {
  // TODO(dmaclach): move this initialization out into session_manager,
  // or at least have session_manager call into here to initialize it.
  CGError err =
      CGRegisterScreenRefreshCallback(CapturerMac::ScreenRefreshCallback,
                                      this);
  DCHECK_EQ(err, kCGErrorSuccess);
  err = CGScreenRegisterMoveCallback(CapturerMac::ScreenUpdateMoveCallback,
                                     this);
  DCHECK_EQ(err, kCGErrorSuccess);
  err = CGDisplayRegisterReconfigurationCallback(
      CapturerMac::DisplaysReconfiguredCallback, this);
  DCHECK_EQ(err, kCGErrorSuccess);
  ScreenConfigurationChanged();
  InvalidateScreen(gfx::Size(width_, height_));
}

CapturerMac::~CapturerMac() {
  ReleaseBuffers();
  CGUnregisterScreenRefreshCallback(CapturerMac::ScreenRefreshCallback, this);
  CGScreenUnregisterMoveCallback(CapturerMac::ScreenUpdateMoveCallback, this);
  CGDisplayRemoveReconfigurationCallback(
      CapturerMac::DisplaysReconfiguredCallback, this);
}

void CapturerMac::ReleaseBuffers() {
  if (cgl_context_) {
    pixel_buffer_object_.Release();
    CGLDestroyContext(cgl_context_);
    cgl_context_ = NULL;
  }
}

void CapturerMac::ScreenConfigurationChanged() {
  ReleaseBuffers();
  CGDirectDisplayID mainDevice = CGMainDisplayID();

  width_ = CGDisplayPixelsWide(mainDevice);
  height_ = CGDisplayPixelsHigh(mainDevice);
  pixel_format_ = media::VideoFrame::RGB32;
  bytes_per_row_ = width_ * sizeof(uint32_t);
  size_t buffer_size = height_ * bytes_per_row_;
  for (int i = 0; i < kNumBuffers; ++i) {
    buffers_[i].reset(new uint8[buffer_size]);
  }
  CGLPixelFormatAttribute attributes[] = {
    kCGLPFAFullScreen,
    kCGLPFADisplayMask,
    (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice),
    (CGLPixelFormatAttribute)0
  };
  CGLPixelFormatObj pixel_format = NULL;
  GLint matching_pixel_format_count = 0;
  CGLError err = CGLChoosePixelFormat(attributes,
                                      &pixel_format,
                                      &matching_pixel_format_count);
  DCHECK_EQ(err, kCGLNoError);
  err = CGLCreateContext(pixel_format, NULL, &cgl_context_);
  DCHECK_EQ(err, kCGLNoError);
  CGLDestroyPixelFormat(pixel_format);
  CGLSetFullScreen(cgl_context_);
  CGLSetCurrentContext(cgl_context_);

  pixel_buffer_object_.Init(cgl_context_, buffer_size);
}

media::VideoFrame::Format CapturerMac::pixel_format() const {
  return pixel_format_;
}

void CapturerMac::ClearInvalidRects() {
  helper_.ClearInvalidRects();
}

void CapturerMac::InvalidateRects(const InvalidRects& inval_rects) {
  helper_.InvalidateRects(inval_rects);
}

void CapturerMac::InvalidateScreen(const gfx::Size& size) {
  helper_.InvalidateScreen(size);
}

void CapturerMac::InvalidateFullScreen() {
  helper_.InvalidateFullScreen();
}

void CapturerMac::CaptureInvalidRects(CaptureCompletedCallback* callback) {
  InvalidRects rects;
  helper_.SwapInvalidRects(rects);
  uint8* current_buffer = buffers_[current_buffer_].get();

  if (pixel_buffer_object_.get() != 0) {
    FastBlit(current_buffer);
  } else {
    SlowBlit(current_buffer);
  }

  DataPlanes planes;
  planes.data[0] = current_buffer + height_ * bytes_per_row_;
  planes.strides[0] = -bytes_per_row_;

  scoped_refptr<CaptureData> data(
      new CaptureData(planes, gfx::Size(width_, height_), pixel_format()));
  data->mutable_dirty_rects() = rects;

  current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
  helper_.set_size_most_recent(data->size());

  callback->Run(data);
  delete callback;
}

void CapturerMac::FastBlit(uint8* buffer) {
  CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
  glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pixel_buffer_object_.get());
  glReadPixels(0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, 0);
  GLubyte* ptr = static_cast<GLubyte*>(
      glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB));
  if (ptr == NULL) {
    // If the buffer can't be mapped, assume that it's no longer valid, release
    // it and fall back on SlowBlit for this (and subsequent) captures.
    pixel_buffer_object_.Release();
    SlowBlit(buffer);
  } else {
    memcpy(buffer, ptr, height_ * bytes_per_row_);
  }
  if (!glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB)) {
    // If glUnmapBuffer returns false, then the contents of the data store are
    // undefined. This might be because the screen mode has changed, in which
    // case it will be recreated in ScreenConfigurationChanged, but releasing
    // the object here is the best option. Capturing will fall back on SlowBlit
    // until such time as the pixel buffer object is recreated.
    pixel_buffer_object_.Release();
  }
  glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
}

void CapturerMac::SlowBlit(uint8* buffer) {
  CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
  glReadBuffer(GL_FRONT);
  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
  glPixelStorei(GL_PACK_ALIGNMENT, 4);  // Force 4-byte alignment.
  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
  // Read a block of pixels from the frame buffer.
  glReadPixels(0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
  glPopClientAttrib();
}

const gfx::Size& CapturerMac::size_most_recent() const {
  return helper_.size_most_recent();
}

void CapturerMac::ScreenRefresh(CGRectCount count, const CGRect *rect_array) {
  InvalidRects rects;
  for (CGRectCount i = 0; i < count; ++i) {
    rects.insert(gfx::Rect(rect_array[i]));
  }
  InvalidateRects(rects);
}

void CapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
                                   size_t count,
                                   const CGRect *rect_array) {
  InvalidRects rects;
  for (CGRectCount i = 0; i < count; ++i) {
    CGRect rect = rect_array[i];
    rects.insert(gfx::Rect(rect));
    rect = CGRectOffset(rect, delta.dX, delta.dY);
    rects.insert(gfx::Rect(rect));
  }
  InvalidateRects(rects);
}

void CapturerMac::ScreenRefreshCallback(CGRectCount count,
                                        const CGRect *rect_array,
                                        void *user_parameter) {
  CapturerMac *capturer = reinterpret_cast<CapturerMac *>(user_parameter);
  capturer->ScreenRefresh(count, rect_array);
}

void CapturerMac::ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta,
                                           size_t count,
                                           const CGRect *rect_array,
                                           void *user_parameter) {
  CapturerMac *capturer = reinterpret_cast<CapturerMac *>(user_parameter);
  capturer->ScreenUpdateMove(delta, count, rect_array);
}

void CapturerMac::DisplaysReconfiguredCallback(
    CGDirectDisplayID display,
    CGDisplayChangeSummaryFlags flags,
    void *user_parameter) {
  if ((display == CGMainDisplayID()) &&
      !(flags & kCGDisplayBeginConfigurationFlag)) {
    CapturerMac *capturer = reinterpret_cast<CapturerMac *>(user_parameter);
    capturer->ScreenConfigurationChanged();
  }
}

}  // namespace

// static
Capturer* Capturer::Create() {
  return new CapturerMac();
}

}  // namespace remoting
<|endoftext|>