<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

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

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

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

/**
  \file    GLFBOTex.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
           Jens Schneider
           tum.3D, Muenchen
  \date    August 2008
*/
#include "GLFBOTex.h"
#include <Controller/Controller.h>

#ifdef WIN32
  #ifndef DEBUG
    #pragma warning( disable : 4189 ) // disable unused var warning
  #endif
#endif

GLuint  GLFBOTex::m_hFBO = 0;
int    GLFBOTex::m_iCount = 0;
bool  GLFBOTex::m_bInitialized = true;

/**
 * Constructor: on first instantiation, generate an FBO.
 * In any case a new dummy texture according to the parameters is generated.
 */

GLFBOTex::GLFBOTex(MasterController* pMasterController, GLenum minfilter, GLenum magfilter, GLenum wrapmode, GLsizei width, GLsizei height, GLenum intformat, unsigned int iSizePerElement, bool bHaveDepth, int iNumBuffers) :
  m_pMasterController(pMasterController),
  m_iSizePerElement(iSizePerElement),
  m_iSizeX(width),
  m_iSizeY(height),
  m_LastDepthTextUnit(0),
  m_iNumBuffers(iNumBuffers)
{
  if (width<1) width=1;
  if (height<1) height=1;
  if (!m_bInitialized) {
    if (GLEW_OK!=glewInit()) {
      T_ERROR("failed to initialize GLEW!");
      return;
    }
    if (!glewGetExtension("GL_EXT_framebuffer_object")) {
      T_ERROR("GL_EXT_framebuffer_object not supported!");
      return;
    }
    m_bInitialized=true;
  }
  glGetError();
  assert(iNumBuffers>0);
  assert(iNumBuffers<5);
  m_hTexture=new GLuint[iNumBuffers];
  m_LastTexUnit=new GLenum[iNumBuffers];
  m_LastAttachment=new GLenum[iNumBuffers];
  for (int i=0; i<m_iNumBuffers; i++) {
    m_LastTexUnit[i]=0;
    m_LastAttachment[i]=GL_COLOR_ATTACHMENT0_EXT+i;
    m_hTexture[i]=0;
  }
  if (m_hFBO==0)
    initFBO();

  {
    GLenum glerr = glGetError();
    if(GL_NO_ERROR != glerr) {
      T_ERROR("Error '%d' during FBO creation!", static_cast<int>(glerr));
      glDeleteFramebuffersEXT(1,&m_hFBO);
      m_hFBO=0;
      return;
    }
  }
  initTextures(minfilter,magfilter,wrapmode,width,height,intformat);
  {
    GLenum glerr = glGetError();
    if(GL_NO_ERROR != glerr) {
      T_ERROR("Error '%d' during texture creation!", static_cast<int>(glerr));
      glDeleteTextures(m_iNumBuffers,m_hTexture);
      delete[] m_hTexture;
      m_hTexture=NULL;
      return;
    }
  }
  if (bHaveDepth) {
#ifdef GLFBOTEX_DEPTH_RENDERBUFFER
    glGenRenderbuffersEXT(1,&m_hDepthBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,width,height);
#else
    glGenTextures(1,&m_hDepthBuffer);
    glBindTexture(GL_TEXTURE_2D,m_hDepthBuffer);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,width,height,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
#endif
  }
  else m_hDepthBuffer=0;

  ++m_iCount;
}

/**
 * Destructor: Delete texture object. If no more instances of
 * GLFBOTex are around, the FBO is deleted as well.
 */
GLFBOTex::~GLFBOTex(void) {
  if (m_hTexture) {
    glDeleteTextures(m_iNumBuffers,m_hTexture);
    delete[] m_hTexture;
    m_hTexture=NULL;
  }
  if (m_LastTexUnit) {
    delete[] m_LastTexUnit;
    m_LastTexUnit=NULL;
  }
  if (m_LastAttachment) {
    delete[] m_LastAttachment;
    m_LastAttachment=NULL;
  }
#ifdef GLFBOTEX_DEPTH_RENDERBUFFER
  if (m_hDepthBuffer) glDeleteRenderbuffersEXT(1,&m_hDepthBuffer);
#else
  if (m_hDepthBuffer) glDeleteTextures(1,&m_hDepthBuffer);
#endif
  m_hDepthBuffer=0;
  --m_iCount;
  if (m_iCount==0) {
    m_pMasterController->DebugOut()->Message(_func_, "FBO released via "
                                                     "destructor call.");
    glDeleteFramebuffersEXT(1,&m_hFBO);
    m_hFBO=0;
  }
}

/**
 * Build a dummy texture according to the parameters.
 */
void GLFBOTex::initTextures(GLenum minfilter,GLenum magfilter,GLenum wrapmode, GLsizei width, GLsizei height, GLenum intformat) {
  MESSAGE("Initializing 2D texture of dimensions: %ux%u",
          static_cast<unsigned int>(width), static_cast<unsigned int>(height));
  glDeleteTextures(m_iNumBuffers,m_hTexture);
  glGenTextures(m_iNumBuffers,m_hTexture);
  for (int i=0; i<m_iNumBuffers; i++) {
    glBindTexture(GL_TEXTURE_2D, m_hTexture[i]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapmode);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapmode);
    int level=0;
    switch (minfilter) {
      case GL_NEAREST_MIPMAP_NEAREST:
      case GL_LINEAR_MIPMAP_NEAREST:
      case GL_NEAREST_MIPMAP_LINEAR:
      case GL_LINEAR_MIPMAP_LINEAR:
        do {
          glTexImage2D(GL_TEXTURE_2D, level, intformat, width, height, 0,
                       GL_RGBA, GL_UNSIGNED_BYTE, NULL);
          width/=2;
          height/=2;
          if (width==0 && height>0) width=1;
          if (width>0 && height==0) height=1;
          ++level;
        } while (width>=1 && height>=1);
        break;
      default:
        glTexImage2D(GL_TEXTURE_2D, 0, intformat, width, height, 0,
                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    }
  }
}

/**
 * Build a new FBO.
 */
void GLFBOTex::initFBO(void) {
  MESSAGE("Initializing FBO...");
  glGenFramebuffersEXT(1, &m_hFBO);
}

/**
 * Check the FBO for consistency.
 */
bool GLFBOTex::CheckFBO(const char* method) {
  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  switch(status) {
    case GL_FRAMEBUFFER_COMPLETE_EXT:
      return true;
    case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
      T_ERROR("%s() - Unsupported Format!",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
      T_ERROR("%s() - Incomplete attachment",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
      T_ERROR("%s() - Incomplete missing attachment",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
      T_ERROR("%s() - Incomplete dimensions",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
      T_ERROR("%s() - Incomplete formats",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
      T_ERROR("%s() - Incomplete draw buffer",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
      T_ERROR("%s() - Incomplete read buffer",method); return false;
    default:  return false;
  }
}

/**
 * Lock texture for writing. Texture may not be bound any more!
 */
void GLFBOTex::Write(unsigned int iTargetBuffer, int iBuffer, bool bCheckBuffer) {
  GLenum target = GL_COLOR_ATTACHMENT0_EXT + iTargetBuffer;

#ifdef _DEBUG
  if (!m_hFBO) {
    T_ERROR("FBO not initialized!");
    return;
  }
#endif

  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,m_hFBO);
  assert(iBuffer>=0);
  assert(iBuffer<m_iNumBuffers);
  m_LastAttachment[iBuffer]=target;
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, target, GL_TEXTURE_2D, m_hTexture[iBuffer], 0);
  if (m_hDepthBuffer) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,m_hDepthBuffer,0);
  if (bCheckBuffer) {
#ifdef _DEBUG
  if (!CheckFBO("Write")) return;
#endif
  }
}

void GLFBOTex::FinishWrite(int iBuffer) {
  glGetError();
  assert(iBuffer>=0);
  assert(iBuffer<m_iNumBuffers);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,m_LastAttachment[iBuffer],GL_TEXTURE_2D,0,0);
  if (m_hDepthBuffer) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,0,0);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
}

void GLFBOTex::Read(unsigned int iTargetUnit, int iBuffer) {
  GLenum texunit = GL_TEXTURE0 + iTargetUnit;
#ifdef _DEBUG
  if (m_LastTexUnit[iBuffer]!=0) {
    T_ERROR("Missing FinishRead()!");
  }
#endif
  assert(iBuffer>=0);
  assert(iBuffer<m_iNumBuffers);
  m_LastTexUnit[iBuffer]=texunit;
  glActiveTextureARB(texunit);
  glBindTexture(GL_TEXTURE_2D,m_hTexture[iBuffer]);
}

void GLFBOTex::ReadDepth(unsigned int iTargetUnit) {
  GLenum texunit = GL_TEXTURE0 + iTargetUnit;
#ifdef _DEBUG
  if (m_LastDepthTextUnit!=0) {
    T_ERROR("Missing FinishDepthRead()!");
  }
#endif
  m_LastDepthTextUnit=texunit;
  glActiveTextureARB(texunit);
  glBindTexture(GL_TEXTURE_2D,m_hDepthBuffer);
}

// Finish reading from the depth texture
void GLFBOTex::FinishDepthRead() {
  glActiveTextureARB(m_LastDepthTextUnit);
  glBindTexture(GL_TEXTURE_2D,0);
  m_LastDepthTextUnit=0;
}

void GLFBOTex::NoDrawBuffer() {
  glDrawBuffer(GL_NONE);
}

void GLFBOTex::OneDrawBuffer() {
  glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
}

void GLFBOTex::TwoDrawBuffers() {
  GLenum twobuffers[]  = { GL_COLOR_ATTACHMENT0_EXT,
                           GL_COLOR_ATTACHMENT1_EXT };
  glDrawBuffers(2, twobuffers);
}

void GLFBOTex::ThreeDrawBuffers() {
  GLenum threebuffers[]  = { GL_COLOR_ATTACHMENT0_EXT,
                            GL_COLOR_ATTACHMENT1_EXT,
                            GL_COLOR_ATTACHMENT2_EXT};
  glDrawBuffers(3, threebuffers);
}

void GLFBOTex::FourDrawBuffers() {
  GLenum fourbuffers[]  = { GL_COLOR_ATTACHMENT0_EXT,
                            GL_COLOR_ATTACHMENT1_EXT,
                            GL_COLOR_ATTACHMENT2_EXT,
                            GL_COLOR_ATTACHMENT3_EXT};
  glDrawBuffers(4, fourbuffers);
}

// Finish reading from this texture
void GLFBOTex::FinishRead(int iBuffer) {
  assert(iBuffer>=0);
  assert(iBuffer<m_iNumBuffers);
  glActiveTextureARB(m_LastTexUnit[iBuffer]);
  glBindTexture(GL_TEXTURE_2D,0);
  m_LastTexUnit[iBuffer]=0;
}
<commit_msg>Initialize m_hTexture early.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

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

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

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

/**
  \file    GLFBOTex.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
           Jens Schneider
           tum.3D, Muenchen
  \date    August 2008
*/
#include "GLFBOTex.h"
#include <Controller/Controller.h>

#ifdef WIN32
  #ifndef DEBUG
    #pragma warning( disable : 4189 ) // disable unused var warning
  #endif
#endif

GLuint  GLFBOTex::m_hFBO = 0;
int    GLFBOTex::m_iCount = 0;
bool  GLFBOTex::m_bInitialized = true;

/**
 * Constructor: on first instantiation, generate an FBO.
 * In any case a new dummy texture according to the parameters is generated.
 */

GLFBOTex::GLFBOTex(MasterController* pMasterController, GLenum minfilter, GLenum magfilter, GLenum wrapmode, GLsizei width, GLsizei height, GLenum intformat, unsigned int iSizePerElement, bool bHaveDepth, int iNumBuffers) :
  m_pMasterController(pMasterController),
  m_iSizePerElement(iSizePerElement),
  m_iSizeX(width),
  m_iSizeY(height),
  m_hTexture(new GLuint[iNumBuffers]),
  m_LastDepthTextUnit(0),
  m_iNumBuffers(iNumBuffers)
{
  if (width<1) width=1;
  if (height<1) height=1;
  if (!m_bInitialized) {
    if (GLEW_OK!=glewInit()) {
      T_ERROR("failed to initialize GLEW!");
      return;
    }
    if (!glewGetExtension("GL_EXT_framebuffer_object")) {
      T_ERROR("GL_EXT_framebuffer_object not supported!");
      return;
    }
    m_bInitialized=true;
  }
  glGetError();
  assert(iNumBuffers>0);
  assert(iNumBuffers<5);
  m_LastTexUnit=new GLenum[iNumBuffers];
  m_LastAttachment=new GLenum[iNumBuffers];
  for (int i=0; i<m_iNumBuffers; i++) {
    m_LastTexUnit[i]=0;
    m_LastAttachment[i]=GL_COLOR_ATTACHMENT0_EXT+i;
    m_hTexture[i]=0;
  }
  if (m_hFBO==0)
    initFBO();

  {
    GLenum glerr = glGetError();
    if(GL_NO_ERROR != glerr) {
      T_ERROR("Error '%d' during FBO creation!", static_cast<int>(glerr));
      glDeleteFramebuffersEXT(1,&m_hFBO);
      m_hFBO=0;
      return;
    }
  }
  initTextures(minfilter,magfilter,wrapmode,width,height,intformat);
  {
    GLenum glerr = glGetError();
    if(GL_NO_ERROR != glerr) {
      T_ERROR("Error '%d' during texture creation!", static_cast<int>(glerr));
      glDeleteTextures(m_iNumBuffers,m_hTexture);
      delete[] m_hTexture;
      m_hTexture=NULL;
      return;
    }
  }
  if (bHaveDepth) {
#ifdef GLFBOTEX_DEPTH_RENDERBUFFER
    glGenRenderbuffersEXT(1,&m_hDepthBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,width,height);
#else
    glGenTextures(1,&m_hDepthBuffer);
    glBindTexture(GL_TEXTURE_2D,m_hDepthBuffer);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,width,height,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
#endif
  }
  else m_hDepthBuffer=0;

  ++m_iCount;
}

/**
 * Destructor: Delete texture object. If no more instances of
 * GLFBOTex are around, the FBO is deleted as well.
 */
GLFBOTex::~GLFBOTex(void) {
  if (m_hTexture) {
    glDeleteTextures(m_iNumBuffers,m_hTexture);
    delete[] m_hTexture;
    m_hTexture=NULL;
  }
  if (m_LastTexUnit) {
    delete[] m_LastTexUnit;
    m_LastTexUnit=NULL;
  }
  if (m_LastAttachment) {
    delete[] m_LastAttachment;
    m_LastAttachment=NULL;
  }
#ifdef GLFBOTEX_DEPTH_RENDERBUFFER
  if (m_hDepthBuffer) glDeleteRenderbuffersEXT(1,&m_hDepthBuffer);
#else
  if (m_hDepthBuffer) glDeleteTextures(1,&m_hDepthBuffer);
#endif
  m_hDepthBuffer=0;
  --m_iCount;
  if (m_iCount==0) {
    m_pMasterController->DebugOut()->Message(_func_, "FBO released via "
                                                     "destructor call.");
    glDeleteFramebuffersEXT(1,&m_hFBO);
    m_hFBO=0;
  }
}

/**
 * Build a dummy texture according to the parameters.
 */
void GLFBOTex::initTextures(GLenum minfilter,GLenum magfilter,GLenum wrapmode, GLsizei width, GLsizei height, GLenum intformat) {
  MESSAGE("Initializing 2D texture of dimensions: %ux%u",
          static_cast<unsigned int>(width), static_cast<unsigned int>(height));
  glDeleteTextures(m_iNumBuffers,m_hTexture);
  glGenTextures(m_iNumBuffers,m_hTexture);
  for (int i=0; i<m_iNumBuffers; i++) {
    glBindTexture(GL_TEXTURE_2D, m_hTexture[i]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapmode);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapmode);
    int level=0;
    switch (minfilter) {
      case GL_NEAREST_MIPMAP_NEAREST:
      case GL_LINEAR_MIPMAP_NEAREST:
      case GL_NEAREST_MIPMAP_LINEAR:
      case GL_LINEAR_MIPMAP_LINEAR:
        do {
          glTexImage2D(GL_TEXTURE_2D, level, intformat, width, height, 0,
                       GL_RGBA, GL_UNSIGNED_BYTE, NULL);
          width/=2;
          height/=2;
          if (width==0 && height>0) width=1;
          if (width>0 && height==0) height=1;
          ++level;
        } while (width>=1 && height>=1);
        break;
      default:
        glTexImage2D(GL_TEXTURE_2D, 0, intformat, width, height, 0,
                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    }
  }
}

/**
 * Build a new FBO.
 */
void GLFBOTex::initFBO(void) {
  MESSAGE("Initializing FBO...");
  glGenFramebuffersEXT(1, &m_hFBO);
}

/**
 * Check the FBO for consistency.
 */
bool GLFBOTex::CheckFBO(const char* method) {
  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  switch(status) {
    case GL_FRAMEBUFFER_COMPLETE_EXT:
      return true;
    case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
      T_ERROR("%s() - Unsupported Format!",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
      T_ERROR("%s() - Incomplete attachment",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
      T_ERROR("%s() - Incomplete missing attachment",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
      T_ERROR("%s() - Incomplete dimensions",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
      T_ERROR("%s() - Incomplete formats",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
      T_ERROR("%s() - Incomplete draw buffer",method); return false;
    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
      T_ERROR("%s() - Incomplete read buffer",method); return false;
    default:  return false;
  }
}

/**
 * Lock texture for writing. Texture may not be bound any more!
 */
void GLFBOTex::Write(unsigned int iTargetBuffer, int iBuffer, bool bCheckBuffer) {
  GLenum target = GL_COLOR_ATTACHMENT0_EXT + iTargetBuffer;

#ifdef _DEBUG
  if (!m_hFBO) {
    T_ERROR("FBO not initialized!");
    return;
  }
#endif

  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,m_hFBO);
  assert(iBuffer>=0);
  assert(iBuffer<m_iNumBuffers);
  m_LastAttachment[iBuffer]=target;
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, target, GL_TEXTURE_2D, m_hTexture[iBuffer], 0);
  if (m_hDepthBuffer) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,m_hDepthBuffer,0);
  if (bCheckBuffer) {
#ifdef _DEBUG
  if (!CheckFBO("Write")) return;
#endif
  }
}

void GLFBOTex::FinishWrite(int iBuffer) {
  glGetError();
  assert(iBuffer>=0);
  assert(iBuffer<m_iNumBuffers);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,m_LastAttachment[iBuffer],GL_TEXTURE_2D,0,0);
  if (m_hDepthBuffer) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,0,0);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
}

void GLFBOTex::Read(unsigned int iTargetUnit, int iBuffer) {
  GLenum texunit = GL_TEXTURE0 + iTargetUnit;
#ifdef _DEBUG
  if (m_LastTexUnit[iBuffer]!=0) {
    T_ERROR("Missing FinishRead()!");
  }
#endif
  assert(iBuffer>=0);
  assert(iBuffer<m_iNumBuffers);
  m_LastTexUnit[iBuffer]=texunit;
  glActiveTextureARB(texunit);
  glBindTexture(GL_TEXTURE_2D,m_hTexture[iBuffer]);
}

void GLFBOTex::ReadDepth(unsigned int iTargetUnit) {
  GLenum texunit = GL_TEXTURE0 + iTargetUnit;
#ifdef _DEBUG
  if (m_LastDepthTextUnit!=0) {
    T_ERROR("Missing FinishDepthRead()!");
  }
#endif
  m_LastDepthTextUnit=texunit;
  glActiveTextureARB(texunit);
  glBindTexture(GL_TEXTURE_2D,m_hDepthBuffer);
}

// Finish reading from the depth texture
void GLFBOTex::FinishDepthRead() {
  glActiveTextureARB(m_LastDepthTextUnit);
  glBindTexture(GL_TEXTURE_2D,0);
  m_LastDepthTextUnit=0;
}

void GLFBOTex::NoDrawBuffer() {
  glDrawBuffer(GL_NONE);
}

void GLFBOTex::OneDrawBuffer() {
  glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
}

void GLFBOTex::TwoDrawBuffers() {
  GLenum twobuffers[]  = { GL_COLOR_ATTACHMENT0_EXT,
                           GL_COLOR_ATTACHMENT1_EXT };
  glDrawBuffers(2, twobuffers);
}

void GLFBOTex::ThreeDrawBuffers() {
  GLenum threebuffers[]  = { GL_COLOR_ATTACHMENT0_EXT,
                            GL_COLOR_ATTACHMENT1_EXT,
                            GL_COLOR_ATTACHMENT2_EXT};
  glDrawBuffers(3, threebuffers);
}

void GLFBOTex::FourDrawBuffers() {
  GLenum fourbuffers[]  = { GL_COLOR_ATTACHMENT0_EXT,
                            GL_COLOR_ATTACHMENT1_EXT,
                            GL_COLOR_ATTACHMENT2_EXT,
                            GL_COLOR_ATTACHMENT3_EXT};
  glDrawBuffers(4, fourbuffers);
}

// Finish reading from this texture
void GLFBOTex::FinishRead(int iBuffer) {
  assert(iBuffer>=0);
  assert(iBuffer<m_iNumBuffers);
  glActiveTextureARB(m_LastTexUnit[iBuffer]);
  glBindTexture(GL_TEXTURE_2D,0);
  m_LastTexUnit[iBuffer]=0;
}
<|endoftext|>


<commit_before><commit_msg>Add SUMPRODUCT and MINVERSE to the list of vectorizable functions.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: drawview.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2004-09-08 13:55:24 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_DRAWVIEW_HXX
#define SC_DRAWVIEW_HXX

#ifndef _SVX_FMVIEW_HXX //autogen
#include <svx/fmview.hxx>
#endif

#include "global.hxx"

class ScDocument;
class ScViewData;
class SdrViewUserMarker;

class ScDrawView: public FmFormView
{
    ScViewData*             pViewData;
    OutputDevice*           pDev;                   //! noetig ?
    ScDocument*             pDoc;
    SCTAB                   nTab;
    Fraction                aScaleX;                // Faktor fuer Drawing-MapMode
    Fraction                aScaleY;
    SdrViewUserMarker*      pDropMarker;
    SdrObject*              pDropMarkObj;
    BOOL                    bInConstruct;
    BOOL                    bDisableHdl;

    void            Construct();
    void            UpdateBrowser();

protected:
    virtual void    ModelHasChanged();
    virtual void    MakeVisible( const Rectangle& rRect, Window& rWin );

    // add custom handles (used by other apps, e.g. AnchorPos)
    virtual void AddCustomHdl();

public:
                    ScDrawView( OutputDevice* pOut, ScViewData* pData );
                    ScDrawView( OutputDevice* pOut, ScDocument* pDocument, SCTAB nTable );
    virtual         ~ScDrawView();

    virtual void    MarkListHasChanged();
    virtual void    SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
                         const SfxHint& rHint, const TypeId& rHintType );

    void            DrawMarks( OutputDevice* pOut ) const;

    void            MarkDropObj( SdrObject* pObj );

    BOOL            IsDisableHdl() const    { return bDisableHdl; }

    void            SetMarkedToLayer( BYTE nLayerNo );

    void            InvalidateAttribs();
    void            InvalidateDrawTextAttrs();

    BOOL            BeginDrag( Window* pWindow, const Point& rStartPos );
    void            DoCut();
    void            DoCopy();

    void            GetScale( Fraction& rFractX, Fraction& rFractY ) const;
    void            RecalcScale();
    void            UpdateWorkArea();
    SCTAB           GetTab() const      { return nTab; }

    void            CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const;

    // #110094#-17 Not used
    // void         PaintObject( SdrObject* pObject, OutputDevice* pDev ) const;

    void            SetAnchor( ScAnchorType );
    ScAnchorType    GetAnchor() const;

    void            VCAddWin( Window* pWin );
    void            VCRemoveWin( Window* pWin );

    void            UpdateIMap( SdrObject* pObj );

    USHORT          GetPopupMenuId();
    void            UpdateUserViewOptions();

    void            SetMarkedOriginalSize();

    BOOL            SelectObject( const String& rName );
    String          GetSelectedChartName() const;
    BOOL            HasMarkedControl() const;

    FASTBOOL        InsertObjectSafe(SdrObject* pObj, SdrPageView& rPV, ULONG nOptions=0);

    SdrEndTextEditKind  ScEndTextEdit();    // ruft SetDrawTextUndo(0)
    void                    StoreCaptionAttribs();
    void                    StoreCaptionDimensions();
};

#endif

<commit_msg>INTEGRATION: CWS calc24 (1.5.42); FILE MERGED 2004/10/13 16:55:46 jmarmion 1.5.42.1: #i33636# - suppport vertical writing for Notes.<commit_after>/*************************************************************************
 *
 *  $RCSfile: drawview.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2004-11-09 18:00:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_DRAWVIEW_HXX
#define SC_DRAWVIEW_HXX

#ifndef _SVX_FMVIEW_HXX //autogen
#include <svx/fmview.hxx>
#endif

#include "global.hxx"

class ScDocument;
class ScViewData;
class SdrViewUserMarker;

class ScDrawView: public FmFormView
{
    ScViewData*             pViewData;
    OutputDevice*           pDev;                   //! noetig ?
    ScDocument*             pDoc;
    SCTAB                   nTab;
    Fraction                aScaleX;                // Faktor fuer Drawing-MapMode
    Fraction                aScaleY;
    SdrViewUserMarker*      pDropMarker;
    SdrObject*              pDropMarkObj;
    BOOL                    bInConstruct;
    BOOL                    bDisableHdl;

    void            Construct();
    void            UpdateBrowser();

protected:
    virtual void    ModelHasChanged();
    virtual void    MakeVisible( const Rectangle& rRect, Window& rWin );

    // add custom handles (used by other apps, e.g. AnchorPos)
    virtual void AddCustomHdl();

public:
                    ScDrawView( OutputDevice* pOut, ScViewData* pData );
                    ScDrawView( OutputDevice* pOut, ScDocument* pDocument, SCTAB nTable );
    virtual         ~ScDrawView();

    virtual void    MarkListHasChanged();
    virtual void    SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
                         const SfxHint& rHint, const TypeId& rHintType );

    void            DrawMarks( OutputDevice* pOut ) const;

    void            MarkDropObj( SdrObject* pObj );

    BOOL            IsDisableHdl() const    { return bDisableHdl; }

    void            SetMarkedToLayer( BYTE nLayerNo );

    void            InvalidateAttribs();
    void            InvalidateDrawTextAttrs();

    BOOL            BeginDrag( Window* pWindow, const Point& rStartPos );
    void            DoCut();
    void            DoCopy();

    void            GetScale( Fraction& rFractX, Fraction& rFractY ) const;
    void            RecalcScale();
    void            UpdateWorkArea();
    SCTAB           GetTab() const      { return nTab; }

    void            CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const;

    // #110094#-17 Not used
    // void         PaintObject( SdrObject* pObject, OutputDevice* pDev ) const;

    void            SetAnchor( ScAnchorType );
    ScAnchorType    GetAnchor() const;

    void            VCAddWin( Window* pWin );
    void            VCRemoveWin( Window* pWin );

    void            UpdateIMap( SdrObject* pObj );

    USHORT          GetPopupMenuId();
    void            UpdateUserViewOptions();

    void            SetMarkedOriginalSize();

    BOOL            SelectObject( const String& rName );
    String          GetSelectedChartName() const;
    BOOL            HasMarkedControl() const;

    FASTBOOL        InsertObjectSafe(SdrObject* pObj, SdrPageView& rPV, ULONG nOptions=0);

    SdrEndTextEditKind  ScEndTextEdit();    // ruft SetDrawTextUndo(0)
    void                    StoreCaptionAttribs();
    void                    StoreCaptionDimensions();
    void                    CaptionTextDirection(USHORT nSlot);
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: instbdlg.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-06-04 11:35:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_INSTBDLG_HXX
#define SC_INSTBDLG_HXX

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#ifndef _GROUP_HXX //autogen
#include <vcl/group.hxx>
#endif
#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif
#ifndef _EDIT_HXX //autogen
#include <vcl/edit.hxx>
#endif
#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _DIALOG_HXX //autogen
#include <vcl/dialog.hxx>
#endif
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
#ifndef _EMBOBJ_HXX //autogen
#include <so3/embobj.hxx>
#endif

#ifndef _SC_EXPFTEXT_HXX
#include "expftext.hxx"
#endif

#ifndef SO2_DECL_SVEMBEDDEDOBJECT_DEFINED
#define SO2_DECL_SVEMBEDDEDOBJECT_DEFINED
SO2_DECL_REF(SvEmbeddedObject)
#endif

class ScViewData;
class ScDocument;
class ScDocShell;

//------------------------------------------------------------------------

class ScInsertTableDlg : public ModalDialog
{
public:
            ScInsertTableDlg( Window* pParent, ScViewData& rViewData, SCTAB nTabCount);
            ~ScInsertTableDlg();

    virtual short   Execute();      // ueberladen, um Dialog-Parent zu setzen

    BOOL            GetTablesFromFile() { return aBtnFromFile.IsChecked(); }
    BOOL            GetTablesAsLink()   { return aBtnLink.IsChecked(); }

    const String*   GetFirstTable( USHORT* pN = NULL );
    const String*   GetNextTable( USHORT* pN = NULL );
    ScDocShell*     GetDocShellTables() { return pDocShTables; }
    BOOL            IsTableBefore() { return aBtnBefore.IsChecked(); }
    SCTAB           GetTableCount() { return nTableCount;}

private:
    RadioButton             aBtnBefore;
    RadioButton             aBtnBehind;
    FixedLine               aFlPos;
    RadioButton             aBtnNew;
    RadioButton             aBtnFromFile;
    FixedText               aFtCount;
    NumericField            aNfCount;
    FixedText               aFtName;
    Edit                    aEdName;
    MultiListBox            aLbTables;
    ScExpandedFixedText     aFtPath;
    PushButton              aBtnBrowse;
    CheckBox                aBtnLink;
    FixedLine               aFlTable;
    OKButton                aBtnOk;
    CancelButton            aBtnCancel;
    HelpButton              aBtnHelp;

    ScViewData&         rViewData;
    ScDocument&         rDoc;
    ScDocShell*         pDocShTables;
    SvEmbeddedObjectRef aDocShTablesRef;

    USHORT              nSelTabIndex;   // fuer GetFirstTable() / GetNextTable()
    String              aStrCurSelTable;
    SCTAB               nTableCount;

#ifdef SC_INSTBDLG_CXX
    void    Init_Impl();
    void    SetNewTable_Impl();
    void    SetFromTo_Impl();
    void    FillTables_Impl( ScDocument* pSrcDoc );
    void    DoEnable_Impl();

    DECL_LINK( BrowseHdl_Impl, PushButton* );
    DECL_LINK( ChoiceHdl_Impl, RadioButton* );
    DECL_LINK( SelectHdl_Impl, MultiListBox* );
    DECL_LINK( CountHdl_Impl, NumericField* );
    DECL_LINK( DoEnterHdl, PushButton* );
#endif
};

#endif // SC_INSTBDLG_HXX

<commit_msg>INTEGRATION: CWS dr21 (1.3.48); FILE MERGED 2004/07/08 10:08:26 dr 1.3.48.1: #i1834# moved from CWS dr20 to CWS dr21<commit_after>/*************************************************************************
 *
 *  $RCSfile: instbdlg.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 11:38:09 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_INSTBDLG_HXX
#define SC_INSTBDLG_HXX

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#ifndef _GROUP_HXX //autogen
#include <vcl/group.hxx>
#endif
#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif
#ifndef _EDIT_HXX //autogen
#include <vcl/edit.hxx>
#endif
#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _DIALOG_HXX //autogen
#include <vcl/dialog.hxx>
#endif
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
#ifndef _EMBOBJ_HXX //autogen
#include <so3/embobj.hxx>
#endif

#ifndef _SC_EXPFTEXT_HXX
#include "expftext.hxx"
#endif

#ifndef SO2_DECL_SVEMBEDDEDOBJECT_DEFINED
#define SO2_DECL_SVEMBEDDEDOBJECT_DEFINED
SO2_DECL_REF(SvEmbeddedObject)
#endif

class ScViewData;
class ScDocument;
class ScDocShell;

//------------------------------------------------------------------------

class ScInsertTableDlg : public ModalDialog
{
public:
            ScInsertTableDlg( Window* pParent, ScViewData& rViewData, SCTAB nTabCount, bool bFromFile );
            ~ScInsertTableDlg();

    virtual short   Execute();      // ueberladen, um Dialog-Parent zu setzen

    BOOL            GetTablesFromFile() { return aBtnFromFile.IsChecked(); }
    BOOL            GetTablesAsLink()   { return aBtnLink.IsChecked(); }

    const String*   GetFirstTable( USHORT* pN = NULL );
    const String*   GetNextTable( USHORT* pN = NULL );
    ScDocShell*     GetDocShellTables() { return pDocShTables; }
    BOOL            IsTableBefore() { return aBtnBefore.IsChecked(); }
    SCTAB           GetTableCount() { return nTableCount;}

private:
    RadioButton             aBtnBefore;
    RadioButton             aBtnBehind;
    FixedLine               aFlPos;
    RadioButton             aBtnNew;
    RadioButton             aBtnFromFile;
    FixedText               aFtCount;
    NumericField            aNfCount;
    FixedText               aFtName;
    Edit                    aEdName;
    MultiListBox            aLbTables;
    ScExpandedFixedText     aFtPath;
    PushButton              aBtnBrowse;
    CheckBox                aBtnLink;
    FixedLine               aFlTable;
    OKButton                aBtnOk;
    CancelButton            aBtnCancel;
    HelpButton              aBtnHelp;

    ScViewData&         rViewData;
    ScDocument&         rDoc;
    ScDocShell*         pDocShTables;
    SvEmbeddedObjectRef aDocShTablesRef;

    USHORT              nSelTabIndex;   // fuer GetFirstTable() / GetNextTable()
    String              aStrCurSelTable;
    SCTAB               nTableCount;

#ifdef SC_INSTBDLG_CXX
    void    Init_Impl( bool bFromFile );
    void    SetNewTable_Impl();
    void    SetFromTo_Impl();
    void    FillTables_Impl( ScDocument* pSrcDoc );
    void    DoEnable_Impl();

    DECL_LINK( BrowseHdl_Impl, PushButton* );
    DECL_LINK( ChoiceHdl_Impl, RadioButton* );
    DECL_LINK( SelectHdl_Impl, MultiListBox* );
    DECL_LINK( CountHdl_Impl, NumericField* );
    DECL_LINK( DoEnterHdl, PushButton* );
#endif
};

#endif // SC_INSTBDLG_HXX

<|endoftext|>


<commit_before>#include "CameraAim.h"
#include "Subsystems/Chassis.h"
#include "Subsystems/Catapult.h"
#include "OI.h"
#include "Misc/Video.h"
#include "Subsystems/Blinkies.h"

CameraAim::CameraAim(Target_side side, bool auton)
	: m_side(side)
	, m_prevAngle(0)
	, m_target(0)
	, m_gotLock(false)
	, m_gotVisual(false)
	, m_auton(auton)
{
	Requires(Chassis::GetInstance());
	Requires(Catapult::GetInstance());
}

// Called just before this Command runs the first time
void CameraAim::Initialize()
{
	m_locationQueue = std::queue<LocationRecord>();
	m_prevAngle = Chassis::GetInstance()->GetAngle();
	RobotVideo::GetInstance()->SetHeadingQueueSize(0);
	RobotVideo::GetInstance()->SetLocationQueueSize(0);
	Chassis::GetInstance()->Shift(true);
	Chassis::GetInstance()->HoldAngle(0);
	m_gotVisual = false;
	m_gotLock = false;
	location_timer.Reset();
	location_timer.Start();
	frame_timer.Reset();
	frame_timer.Start();
	cycle_timer.Reset();
	cycle_timer.Start();
}

void CameraAim::SetParam(Target_side kSide)
{
	m_side = kSide;
}

/**
 * \brief Magic function that returns desired stop angle in rope inches
 *
 * The data collected from repeated shooting at the last night of the build
 * season suggest that the stop angle of the catapult is pretty much a linear
 * function. Here we are going to account for the robot's velocity related
 * to the tower.
 */
double calculateStop(double dist, double speed=0)
{
	// Interpolated by Google Spreadsheets: boulder's horizontal velocity at certain distance
	double velocity = -5.955e-3 * dist * dist +2.141 * dist +77.056;
	double phase = dist / velocity;

	// Phase is the time a boulder takes to get to the target. Adjust distance accordingly
	dist -= speed * phase;
	if (dist > 192) return 17;

	double stop = 0;
	//64	14.15
	//94	16.3
	//148	16.9
	//192	17

	if (dist < 94) stop = 14.5 + (16.3-14.15)*(dist-64);
	else if (dist < 148) stop = 16.3 + (16.9-16.3)*(dist-94);
	else stop = 16.9 + 0.1*(dist-148);

	return stop - Preferences::GetInstance()->GetDouble("Vision Hight Offset", 0);
}

// Called repeatedly when this Command is scheduled to run
void CameraAim::Execute()
{
	Chassis *chassis = Chassis::GetInstance();
	OI* oi = OI::GetInstance();
	if (chassis == nullptr or oi == nullptr) return;

	if (!m_gotVisual or frame_timer.Get() > Preferences::GetInstance()->GetDouble("CameraCooldown", AIM_COOLDOWN)) {
		float turn = 0;
		float dist = 0;
		size_t nTurns = 0;

		RobotVideo::GetInstance()->mutex_lock();
		nTurns = RobotVideo::GetInstance()->HaveHeading();
		if(nTurns > 0) {
			turn = RobotVideo::GetInstance()->GetTurn(0);
			dist = RobotVideo::GetInstance()->GetDistance(0);
		}
		if(m_side == kRight and nTurns > 1) {
			turn = RobotVideo::GetInstance()->GetTurn(1);
			dist = RobotVideo::GetInstance()->GetDistance(1);
		}
		RobotVideo::GetInstance()->mutex_unlock();

		if (nTurns > 0) {
			if (dist > 0) {
				// Clear the queue of expired records if any
				double expirationTime = location_timer.Get() - Preferences::GetInstance()->GetDouble("CameraLag", 0.25);
				while (!m_locationQueue.empty() and m_locationQueue.front().time < expirationTime)
					m_locationQueue.pop();

				// Calculate chassis's speed as location change over passed time...
				// if enabled and correct data is available
				double speed = 0;
				if (SmartDashboard::GetBoolean("DB/Button 0",false) and !m_locationQueue.empty()) {
					double dX = chassis->GetDistance() - m_locationQueue.front().dist;
					double dT = location_timer.Get() - m_locationQueue.front().time;
					if (dT > 0) speed = dX / dT;
					// Also adjust distance to target since all this is Camera Lag based
					dist -= dX;
				}

				// Call the Magic function to determine the stop angle.
				float catStop = calculateStop(dist, speed);
				if (catStop > Catapult::TOP_ZONE) catStop = Catapult::TOP_ZONE;
				if (catStop < Catapult::SLOW_ZONE) catStop = Catapult::SLOW_ZONE;
				Catapult::GetInstance()->toSetpoint(catStop);

				// The camera offset over the distance is the adjustment angle's tangent
				turn += (180.0/M_PI) * atan2f(Preferences::GetInstance()->GetFloat("CameraOffset",RobotVideo::CAMERA_OFFSET), dist);
				double camTolerance = (180.0/M_PI) * atan2f(Preferences::GetInstance()->GetDouble("CameraTolerance", 3.5), dist);
				camTolerance -= Preferences::GetInstance()->GetDouble("CameraDeviation", 0.8);
				if (camTolerance < 0.1) camTolerance = 0.1;
				m_gotLock = fabs(turn) < camTolerance;
				int proxima = 0;
				if (!m_gotLock && camTolerance > 0) proxima = abs(turn / camTolerance);
				if (proxima > 9) proxima = 9;
				Blinkies::PutCommand("Aim_", proxima);
			}
			chassis->HoldAngle(turn);
			frame_timer.Reset();
			m_target = turn;
			m_gotVisual = true;
		}
		else {
			m_gotVisual = false;
		}
	}
	else if (cycle_timer.Get() > 0) {
		double angular_v = (chassis->GetAngle() - m_prevAngle) / cycle_timer.Get();
		if (fabs(angular_v) > Preferences::GetInstance()->GetDouble("AngularVelocity", MAX_ANGULAR_V)
			or fabs(chassis->GetPIDError()) > Preferences::GetInstance()->GetDouble("AimResetAngle", 0.5))
			frame_timer.Reset();

		// Take this measurement for tuning purposes. Remove after the tuning is done
		SmartDashboard::PutNumber("Angular Velocity", angular_v);
	}

	m_prevAngle = chassis->GetAngle();
	cycle_timer.Reset();

	LocationRecord record;
	record.dist = chassis->GetDistance();
	record.time = location_timer.Get();
	m_locationQueue.push(record);

	// Check the catapult output current for safety
	if (Catapult::GetInstance()->WatchCurrent()) Catapult::GetInstance()->moveCatapult(0);

	// Drive forward or back while aiming
	double moveSpeed = -oi->stickL->GetY();
	moveSpeed *= fabs(moveSpeed); // Square it here so the drivers will feel like it's squared
	chassis->DriveStraight(moveSpeed);
}

// Make this return true when this Command no longer needs to run execute()
bool CameraAim::IsFinished()
{
	if (m_gotVisual and m_gotLock) {
		SmartDashboard::PutBoolean("Target locked", true);
		SmartDashboard::PutBoolean("DB/LED 0", true);
		if (m_auton) return true;
	}
	else {
		SmartDashboard::PutBoolean("Target locked", false);
		SmartDashboard::PutBoolean("DB/LED 0", false);
	}
	return false;
}

// Called once after isFinished returns true
void CameraAim::End()
{
	SmartDashboard::PutBoolean("Target locked", false);
	SmartDashboard::PutBoolean("DB/LED 0", false);
}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
void CameraAim::Interrupted()
{
	End();
}
<commit_msg>Normalize the diff in stop angle formula<commit_after>#include "CameraAim.h"
#include "Subsystems/Chassis.h"
#include "Subsystems/Catapult.h"
#include "OI.h"
#include "Misc/Video.h"
#include "Subsystems/Blinkies.h"

CameraAim::CameraAim(Target_side side, bool auton)
	: m_side(side)
	, m_prevAngle(0)
	, m_target(0)
	, m_gotLock(false)
	, m_gotVisual(false)
	, m_auton(auton)
{
	Requires(Chassis::GetInstance());
	Requires(Catapult::GetInstance());
}

// Called just before this Command runs the first time
void CameraAim::Initialize()
{
	m_locationQueue = std::queue<LocationRecord>();
	m_prevAngle = Chassis::GetInstance()->GetAngle();
	RobotVideo::GetInstance()->SetHeadingQueueSize(0);
	RobotVideo::GetInstance()->SetLocationQueueSize(0);
	Chassis::GetInstance()->Shift(true);
	Chassis::GetInstance()->HoldAngle(0);
	m_gotVisual = false;
	m_gotLock = false;
	location_timer.Reset();
	location_timer.Start();
	frame_timer.Reset();
	frame_timer.Start();
	cycle_timer.Reset();
	cycle_timer.Start();
}

void CameraAim::SetParam(Target_side kSide)
{
	m_side = kSide;
}

/**
 * \brief Magic function that returns desired stop angle in rope inches
 *
 * The data collected from repeated shooting at the last night of the build
 * season suggest that the stop angle of the catapult is pretty much a linear
 * function. Here we are going to account for the robot's velocity related
 * to the tower.
 */
double calculateStop(double dist, double speed=0)
{
	// Interpolated by Google Spreadsheets: boulder's horizontal velocity at certain distance
	double velocity = -5.955e-3 * dist * dist +2.141 * dist +77.056;
	double phase = dist / velocity;

	// Phase is the time a boulder takes to get to the target. Adjust distance accordingly
	dist -= speed * phase;
	if (dist > 192) return 17;

	double stop = 0;
	//64	14.15
	//94	16.3
	//148	16.9
	//192	17

	if (dist < 94) stop = 14.5 + (16.3-14.15)*(dist-64)/(94-64);
	else if (dist < 148) stop = 16.3 + (16.9-16.3)*(dist-94)/(148-94);
	else stop = 16.9 + 0.1*(dist-148)/(192-148);

	return stop - Preferences::GetInstance()->GetDouble("Vision Hight Offset", 0);
}

// Called repeatedly when this Command is scheduled to run
void CameraAim::Execute()
{
	Chassis *chassis = Chassis::GetInstance();
	OI* oi = OI::GetInstance();
	if (chassis == nullptr or oi == nullptr) return;

	if (!m_gotVisual or frame_timer.Get() > Preferences::GetInstance()->GetDouble("CameraCooldown", AIM_COOLDOWN)) {
		float turn = 0;
		float dist = 0;
		size_t nTurns = 0;

		RobotVideo::GetInstance()->mutex_lock();
		nTurns = RobotVideo::GetInstance()->HaveHeading();
		if(nTurns > 0) {
			turn = RobotVideo::GetInstance()->GetTurn(0);
			dist = RobotVideo::GetInstance()->GetDistance(0);
		}
		if(m_side == kRight and nTurns > 1) {
			turn = RobotVideo::GetInstance()->GetTurn(1);
			dist = RobotVideo::GetInstance()->GetDistance(1);
		}
		RobotVideo::GetInstance()->mutex_unlock();

		if (nTurns > 0) {
			if (dist > 0) {
				// Clear the queue of expired records if any
				double expirationTime = location_timer.Get() - Preferences::GetInstance()->GetDouble("CameraLag", 0.25);
				while (!m_locationQueue.empty() and m_locationQueue.front().time < expirationTime)
					m_locationQueue.pop();

				// Calculate chassis's speed as location change over passed time...
				// if enabled and correct data is available
				double speed = 0;
				if (SmartDashboard::GetBoolean("DB/Button 0",false) and !m_locationQueue.empty()) {
					double dX = chassis->GetDistance() - m_locationQueue.front().dist;
					double dT = location_timer.Get() - m_locationQueue.front().time;
					if (dT > 0) speed = dX / dT;
					// Also adjust distance to target since all this is Camera Lag based
					dist -= dX;
				}

				// Call the Magic function to determine the stop angle.
				float catStop = calculateStop(dist, speed);
				if (catStop > Catapult::TOP_ZONE) catStop = Catapult::TOP_ZONE;
				if (catStop < Catapult::SLOW_ZONE) catStop = Catapult::SLOW_ZONE;
				Catapult::GetInstance()->toSetpoint(catStop);

				// The camera offset over the distance is the adjustment angle's tangent
				turn += (180.0/M_PI) * atan2f(Preferences::GetInstance()->GetFloat("CameraOffset",RobotVideo::CAMERA_OFFSET), dist);
				double camTolerance = (180.0/M_PI) * atan2f(Preferences::GetInstance()->GetDouble("CameraTolerance", 3.5), dist);
				camTolerance -= Preferences::GetInstance()->GetDouble("CameraDeviation", 0.8);
				if (camTolerance < 0.1) camTolerance = 0.1;
				m_gotLock = fabs(turn) < camTolerance;
				int proxima = 0;
				if (!m_gotLock && camTolerance > 0) proxima = abs(turn / camTolerance);
				if (proxima > 9) proxima = 9;
				Blinkies::PutCommand("Aim_", proxima);
			}
			chassis->HoldAngle(turn);
			frame_timer.Reset();
			m_target = turn;
			m_gotVisual = true;
		}
		else {
			m_gotVisual = false;
		}
	}
	else if (cycle_timer.Get() > 0) {
		double angular_v = (chassis->GetAngle() - m_prevAngle) / cycle_timer.Get();
		if (fabs(angular_v) > Preferences::GetInstance()->GetDouble("AngularVelocity", MAX_ANGULAR_V)
			or fabs(chassis->GetPIDError()) > Preferences::GetInstance()->GetDouble("AimResetAngle", 0.5))
			frame_timer.Reset();

		// Take this measurement for tuning purposes. Remove after the tuning is done
		SmartDashboard::PutNumber("Angular Velocity", angular_v);
	}

	m_prevAngle = chassis->GetAngle();
	cycle_timer.Reset();

	LocationRecord record;
	record.dist = chassis->GetDistance();
	record.time = location_timer.Get();
	m_locationQueue.push(record);

	// Check the catapult output current for safety
	if (Catapult::GetInstance()->WatchCurrent()) Catapult::GetInstance()->moveCatapult(0);

	// Drive forward or back while aiming
	double moveSpeed = -oi->stickL->GetY();
	moveSpeed *= fabs(moveSpeed); // Square it here so the drivers will feel like it's squared
	chassis->DriveStraight(moveSpeed);
}

// Make this return true when this Command no longer needs to run execute()
bool CameraAim::IsFinished()
{
	if (m_gotVisual and m_gotLock) {
		SmartDashboard::PutBoolean("Target locked", true);
		SmartDashboard::PutBoolean("DB/LED 0", true);
		if (m_auton) return true;
	}
	else {
		SmartDashboard::PutBoolean("Target locked", false);
		SmartDashboard::PutBoolean("DB/LED 0", false);
	}
	return false;
}

// Called once after isFinished returns true
void CameraAim::End()
{
	SmartDashboard::PutBoolean("Target locked", false);
	SmartDashboard::PutBoolean("DB/LED 0", false);
}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
void CameraAim::Interrupted()
{
	End();
}
<|endoftext|>


<commit_before>// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <new>

#include "SkPaintContext.h"

#include "SkColorPriv.h"
#include "SkShader.h"
#include "SkDashPathEffect.h"

namespace {

int RoundToInt(float x) {
  // Android uses roundf which VC doesn't have, emulate that function.
  if (fmodf(x, 1.0f) >= 0.5f)
    return (int)ceilf(x);
  return (int)floorf(x);
}

}

/*  TODO / questions

    mAlpha: how does this interact with the alpha in Color? multiply them together?
    mPorterDuffMode: do I always respect this? If so, then
                     the rgb() & 0xFF000000 check will abort drawing too often
    Is Color premultiplied or not? If it is, then I can't blindly pass it to paint.setColor()
*/
struct SkPaintContext::State {
  float               mMiterLimit;
  float               mAlpha;
  SkDrawLooper*       mLooper;
  SkPaint::Cap        mLineCap;
  SkPaint::Join       mLineJoin;
  SkPorterDuff::Mode  mPorterDuffMode;
  // Ratio of the length of a dash to its width.
  int                 mDashRatio;
  SkColor             mFillColor;
  StrokeStyle         mStrokeStyle;
  SkColor             mStrokeColor;
  float               mStrokeThickness;
  bool                mUseAntialiasing;

  SkDashPathEffect*   mDash;
  SkShader*           mGradient;
  SkShader*           mPattern;

  // Note: Keep theses default values in sync with GraphicsContextState.
  State()
      : mMiterLimit(4),
        mAlpha(1),
        mLooper(NULL),
        mLineCap(SkPaint::kDefault_Cap),
        mLineJoin(SkPaint::kDefault_Join),
        mPorterDuffMode(SkPorterDuff::kSrcOver_Mode),
        mDashRatio(3),
        mFillColor(0xFF000000),
        mStrokeStyle(SolidStroke),
        mStrokeColor(0x0FF000000),
        mStrokeThickness(0),
        mUseAntialiasing(true),
        mDash(NULL),
        mGradient(NULL),
        mPattern(NULL) {
  }

  State(const State& other) {
    other.mLooper->safeRef();
    memcpy(this, &other, sizeof(State));

    mDash->safeRef();
    mGradient->safeRef();
    mPattern->safeRef();
  }

  ~State() {
    mLooper->safeUnref();
    mDash->safeUnref();
    mGradient->safeUnref();
    mPattern->safeUnref();
  }

  SkDrawLooper* setDrawLooper(SkDrawLooper* dl) {
    SkRefCnt_SafeAssign(mLooper, dl);
    return dl;
  }

  SkColor applyAlpha(SkColor c) const {
    int s = RoundToInt(mAlpha * 256);
    if (s >= 256)
      return c;
    if (s < 0)
      return 0;

    int a = SkAlphaMul(SkColorGetA(c), s);
    return (c & 0x00FFFFFF) | (a << 24);
  }

 private:
  // Not supported yet.
  void operator=(const State&);
};

// Context will be NULL if painting should be disabled.
SkPaintContext::SkPaintContext(gfx::PlatformCanvas* context)
      : canvas_(context),
        state_stack_(sizeof(State)) {
  State* state = reinterpret_cast<State*>(state_stack_.push_back());
  new (state) State();
  state_ = state;
}

SkPaintContext::~SkPaintContext() {
  // we force restores so we don't leak any subobjects owned by our
  // stack of State records.
  while (state_stack_.count() > 0) {
    reinterpret_cast<State*>(state_stack_.back())->~State();
    state_stack_.pop_back();
  }
}

void SkPaintContext::save() {
  State* newState = reinterpret_cast<State*>(state_stack_.push_back());
  new (newState) State(*state_);
  state_ = newState;

  // Save our native canvas.
  canvas()->save();
}

void SkPaintContext::restore() {
  // Restore our native canvas.
  canvas()->restore();

  state_->~State();
  state_stack_.pop_back();

  state_ = reinterpret_cast<State*>(state_stack_.back());
}

void SkPaintContext::drawRect(SkRect rect) {
  SkPaint paint;
  int fillcolor_not_transparent = state_->mFillColor & 0xFF000000;
  if (fillcolor_not_transparent) {
    setup_paint_fill(&paint);
    canvas()->drawRect(rect, paint);
  }

  if (state_->mStrokeStyle != NoStroke && (state_->mStrokeColor & 0xFF000000)) {
    if (fillcolor_not_transparent) {
      // This call is expensive so don't call it unnecessarily.
      paint.reset();
    }
    setup_paint_stroke(&paint, &rect, 0);
    canvas()->drawRect(rect, paint);
  }
}

void SkPaintContext::setup_paint_common(SkPaint* paint) const {
#ifdef SK_DEBUGx
  {
    SkPaint defaultPaint;
    SkASSERT(*paint == defaultPaint);
  }
#endif

  paint->setAntiAlias(state_->mUseAntialiasing);
  paint->setPorterDuffXfermode(state_->mPorterDuffMode);
  paint->setLooper(state_->mLooper);

  if(state_->mGradient) {
    paint->setShader(state_->mGradient);
  } else if (state_->mPattern) {
    paint->setShader(state_->mPattern);
  }
}

void SkPaintContext::setup_paint_fill(SkPaint* paint) const {
  setup_paint_common(paint);
  paint->setColor(state_->applyAlpha(state_->mFillColor));
}

int SkPaintContext::setup_paint_stroke(SkPaint* paint,
                                       SkRect* rect,
                                       int length) {
  setup_paint_common(paint);
  float width = state_->mStrokeThickness;

  //this allows dashing and dotting to work properly for hairline strokes
  if (0 == width)
    width = 1;

  paint->setColor(state_->applyAlpha(state_->mStrokeColor));
  paint->setStyle(SkPaint::kStroke_Style);
  paint->setStrokeWidth(SkFloatToScalar(width));
  paint->setStrokeCap(state_->mLineCap);
  paint->setStrokeJoin(state_->mLineJoin);
  paint->setStrokeMiter(SkFloatToScalar(state_->mMiterLimit));

  if (rect != NULL && (RoundToInt(width) & 1)) {
    rect->inset(-SK_ScalarHalf, -SK_ScalarHalf);
  }

  if (state_->mDash) {
    paint->setPathEffect(state_->mDash);
  } else {
    switch (state_->mStrokeStyle) {
    case NoStroke:
    case SolidStroke:
      break;
    case DashedStroke:
      width = state_->mDashRatio * width;
      /* no break */
    case DottedStroke:
      SkScalar dashLength;
      if (length) {
        //determine about how many dashes or dots we should have
        int numDashes = length/RoundToInt(width);
        if (!(numDashes & 1))
          numDashes++;    //make it odd so we end on a dash/dot
        //use the number of dashes to determine the length of a dash/dot, which will be approximately width
        dashLength = SkScalarDiv(SkIntToScalar(length), SkIntToScalar(numDashes));
      } else {
        dashLength = SkFloatToScalar(width);
      }
      SkScalar intervals[2] = { dashLength, dashLength };
      paint->setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref();
    }
  }
  return RoundToInt(width);
}

SkDrawLooper* SkPaintContext::setDrawLooper(SkDrawLooper* dl) {
  return state_->setDrawLooper(dl);
}

void SkPaintContext::setMiterLimit(float ml) {
  state_->mMiterLimit = ml;
}

void SkPaintContext::setAlpha(float alpha) {
  state_->mAlpha = alpha;
}

void SkPaintContext::setLineCap(SkPaint::Cap lc) {
  state_->mLineCap = lc;
}

void SkPaintContext::setLineJoin(SkPaint::Join lj) {
  state_->mLineJoin = lj;
}

void SkPaintContext::setPorterDuffMode(SkPorterDuff::Mode pdm) {
  state_->mPorterDuffMode = pdm;
}

void SkPaintContext::setFillColor(SkColor color) {
  state_->mFillColor = color;
}

void SkPaintContext::setStrokeStyle(StrokeStyle strokestyle) {
  state_->mStrokeStyle = strokestyle;
}

void SkPaintContext::setStrokeColor(SkColor strokecolor) {
  state_->mStrokeColor = strokecolor;
}

void SkPaintContext::setStrokeThickness(float thickness) {
  state_->mStrokeThickness = thickness;
}

void SkPaintContext::setUseAntialiasing(bool enable) {
  state_->mUseAntialiasing = enable;
}

SkColor SkPaintContext::fillColor() const {
  return state_->mFillColor;
}

void SkPaintContext::beginPath() {
  path_.reset();
}

void SkPaintContext::addPath(const SkPath& path) {
  path_.addPath(path);
}

SkPath* SkPaintContext::currentPath() {
  return &path_;
}

void SkPaintContext::setFillRule(SkPath::FillType fr) {
  path_.setFillType(fr);
}

void SkPaintContext::setGradient(SkShader* gradient) {
  if (gradient != state_->mGradient) {
    state_->mGradient->safeUnref();
    state_->mGradient=gradient;
  }
}

void SkPaintContext::setPattern(SkShader* pattern) {
  if (pattern != state_->mPattern) {
    state_->mPattern->safeUnref();
    state_->mPattern=pattern;
  }
}

void SkPaintContext::setDashPathEffect(SkDashPathEffect* dash) {
  if (dash != state_->mDash) {
    state_->mDash->safeUnref();
    state_->mDash=dash;
  }
}

<commit_msg>Nevermind... re-check in 2882 (unrevert). Huanr has checked in a more promising rollback of V8.<commit_after>// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "config.h"

#include "SkPaintContext.h"

#include "SkColorPriv.h"
#include "SkShader.h"
#include "SkDashPathEffect.h"

namespace {

int RoundToInt(float x) {
  // Android uses roundf which VC doesn't have, emulate that function.
  if (fmodf(x, 1.0f) >= 0.5f)
    return (int)ceilf(x);
  return (int)floorf(x);
}

}

/*  TODO / questions

    mAlpha: how does this interact with the alpha in Color? multiply them together?
    mPorterDuffMode: do I always respect this? If so, then
                     the rgb() & 0xFF000000 check will abort drawing too often
    Is Color premultiplied or not? If it is, then I can't blindly pass it to paint.setColor()
*/
struct SkPaintContext::State {
  float               mMiterLimit;
  float               mAlpha;
  SkDrawLooper*       mLooper;
  SkPaint::Cap        mLineCap;
  SkPaint::Join       mLineJoin;
  SkPorterDuff::Mode  mPorterDuffMode;
  // Ratio of the length of a dash to its width.
  int                 mDashRatio;
  SkColor             mFillColor;
  StrokeStyle         mStrokeStyle;
  SkColor             mStrokeColor;
  float               mStrokeThickness;
  bool                mUseAntialiasing;

  SkDashPathEffect*   mDash;
  SkShader*           mGradient;
  SkShader*           mPattern;

  // Note: Keep theses default values in sync with GraphicsContextState.
  State()
      : mMiterLimit(4),
        mAlpha(1),
        mLooper(NULL),
        mLineCap(SkPaint::kDefault_Cap),
        mLineJoin(SkPaint::kDefault_Join),
        mPorterDuffMode(SkPorterDuff::kSrcOver_Mode),
        mDashRatio(3),
        mFillColor(0xFF000000),
        mStrokeStyle(SolidStroke),
        mStrokeColor(0x0FF000000),
        mStrokeThickness(0),
        mUseAntialiasing(true),
        mDash(NULL),
        mGradient(NULL),
        mPattern(NULL) {
  }

  State(const State& other) {
    other.mLooper->safeRef();
    memcpy(this, &other, sizeof(State));

    mDash->safeRef();
    mGradient->safeRef();
    mPattern->safeRef();
  }

  ~State() {
    mLooper->safeUnref();
    mDash->safeUnref();
    mGradient->safeUnref();
    mPattern->safeUnref();
  }

  SkDrawLooper* setDrawLooper(SkDrawLooper* dl) {
    SkRefCnt_SafeAssign(mLooper, dl);
    return dl;
  }

  SkColor applyAlpha(SkColor c) const {
    int s = RoundToInt(mAlpha * 256);
    if (s >= 256)
      return c;
    if (s < 0)
      return 0;

    int a = SkAlphaMul(SkColorGetA(c), s);
    return (c & 0x00FFFFFF) | (a << 24);
  }

 private:
  // Not supported yet.
  void operator=(const State&);
};

// Context will be NULL if painting should be disabled.
SkPaintContext::SkPaintContext(gfx::PlatformCanvas* context)
      : canvas_(context),
        state_stack_(sizeof(State)) {
  State* state = reinterpret_cast<State*>(state_stack_.push_back());
  new (state) State();
  state_ = state;
}

SkPaintContext::~SkPaintContext() {
  // we force restores so we don't leak any subobjects owned by our
  // stack of State records.
  while (state_stack_.count() > 0) {
    reinterpret_cast<State*>(state_stack_.back())->~State();
    state_stack_.pop_back();
  }
}

void SkPaintContext::save() {
  State* newState = reinterpret_cast<State*>(state_stack_.push_back());
  new (newState) State(*state_);
  state_ = newState;

  // Save our native canvas.
  canvas()->save();
}

void SkPaintContext::restore() {
  // Restore our native canvas.
  canvas()->restore();

  state_->~State();
  state_stack_.pop_back();

  state_ = reinterpret_cast<State*>(state_stack_.back());
}

void SkPaintContext::drawRect(SkRect rect) {
  SkPaint paint;
  int fillcolor_not_transparent = state_->mFillColor & 0xFF000000;
  if (fillcolor_not_transparent) {
    setup_paint_fill(&paint);
    canvas()->drawRect(rect, paint);
  }

  if (state_->mStrokeStyle != NoStroke && (state_->mStrokeColor & 0xFF000000)) {
    if (fillcolor_not_transparent) {
      // This call is expensive so don't call it unnecessarily.
      paint.reset();
    }
    setup_paint_stroke(&paint, &rect, 0);
    canvas()->drawRect(rect, paint);
  }
}

void SkPaintContext::setup_paint_common(SkPaint* paint) const {
#ifdef SK_DEBUGx
  {
    SkPaint defaultPaint;
    SkASSERT(*paint == defaultPaint);
  }
#endif

  paint->setAntiAlias(state_->mUseAntialiasing);
  paint->setPorterDuffXfermode(state_->mPorterDuffMode);
  paint->setLooper(state_->mLooper);

  if(state_->mGradient) {
    paint->setShader(state_->mGradient);
  } else if (state_->mPattern) {
    paint->setShader(state_->mPattern);
  }
}

void SkPaintContext::setup_paint_fill(SkPaint* paint) const {
  setup_paint_common(paint);
  paint->setColor(state_->applyAlpha(state_->mFillColor));
}

int SkPaintContext::setup_paint_stroke(SkPaint* paint,
                                       SkRect* rect,
                                       int length) {
  setup_paint_common(paint);
  float width = state_->mStrokeThickness;

  //this allows dashing and dotting to work properly for hairline strokes
  if (0 == width)
    width = 1;

  paint->setColor(state_->applyAlpha(state_->mStrokeColor));
  paint->setStyle(SkPaint::kStroke_Style);
  paint->setStrokeWidth(SkFloatToScalar(width));
  paint->setStrokeCap(state_->mLineCap);
  paint->setStrokeJoin(state_->mLineJoin);
  paint->setStrokeMiter(SkFloatToScalar(state_->mMiterLimit));

  if (rect != NULL && (RoundToInt(width) & 1)) {
    rect->inset(-SK_ScalarHalf, -SK_ScalarHalf);
  }

  if (state_->mDash) {
    paint->setPathEffect(state_->mDash);
  } else {
    switch (state_->mStrokeStyle) {
    case NoStroke:
    case SolidStroke:
      break;
    case DashedStroke:
      width = state_->mDashRatio * width;
      /* no break */
    case DottedStroke:
      SkScalar dashLength;
      if (length) {
        //determine about how many dashes or dots we should have
        int numDashes = length/RoundToInt(width);
        if (!(numDashes & 1))
          numDashes++;    //make it odd so we end on a dash/dot
        //use the number of dashes to determine the length of a dash/dot, which will be approximately width
        dashLength = SkScalarDiv(SkIntToScalar(length), SkIntToScalar(numDashes));
      } else {
        dashLength = SkFloatToScalar(width);
      }
      SkScalar intervals[2] = { dashLength, dashLength };
      paint->setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref();
    }
  }
  return RoundToInt(width);
}

SkDrawLooper* SkPaintContext::setDrawLooper(SkDrawLooper* dl) {
  return state_->setDrawLooper(dl);
}

void SkPaintContext::setMiterLimit(float ml) {
  state_->mMiterLimit = ml;
}

void SkPaintContext::setAlpha(float alpha) {
  state_->mAlpha = alpha;
}

void SkPaintContext::setLineCap(SkPaint::Cap lc) {
  state_->mLineCap = lc;
}

void SkPaintContext::setLineJoin(SkPaint::Join lj) {
  state_->mLineJoin = lj;
}

void SkPaintContext::setPorterDuffMode(SkPorterDuff::Mode pdm) {
  state_->mPorterDuffMode = pdm;
}

void SkPaintContext::setFillColor(SkColor color) {
  state_->mFillColor = color;
}

void SkPaintContext::setStrokeStyle(StrokeStyle strokestyle) {
  state_->mStrokeStyle = strokestyle;
}

void SkPaintContext::setStrokeColor(SkColor strokecolor) {
  state_->mStrokeColor = strokecolor;
}

void SkPaintContext::setStrokeThickness(float thickness) {
  state_->mStrokeThickness = thickness;
}

void SkPaintContext::setUseAntialiasing(bool enable) {
  state_->mUseAntialiasing = enable;
}

SkColor SkPaintContext::fillColor() const {
  return state_->mFillColor;
}

void SkPaintContext::beginPath() {
  path_.reset();
}

void SkPaintContext::addPath(const SkPath& path) {
  path_.addPath(path);
}

SkPath* SkPaintContext::currentPath() {
  return &path_;
}

void SkPaintContext::setFillRule(SkPath::FillType fr) {
  path_.setFillType(fr);
}

void SkPaintContext::setGradient(SkShader* gradient) {
  if (gradient != state_->mGradient) {
    state_->mGradient->safeUnref();
    state_->mGradient=gradient;
  }
}

void SkPaintContext::setPattern(SkShader* pattern) {
  if (pattern != state_->mPattern) {
    state_->mPattern->safeUnref();
    state_->mPattern=pattern;
  }
}

void SkPaintContext::setDashPathEffect(SkDashPathEffect* dash) {
  if (dash != state_->mDash) {
    state_->mDash->safeUnref();
    state_->mDash=dash;
  }
}

<|endoftext|>


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

#include "config.h"
#include <wtf/MainThread.h>
#include <wtf/Threading.h>
#undef LOG

#include "build/build_config.h"

#include "webkit/tools/test_shell/test_webworker_helper.h"

#if defined(OS_MACOSX)
#include <dlfcn.h>
#endif

#include "base/logging.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "third_party/WebKit/WebKit/chromium/public/WebKit.h"
#include "webkit/glue/webworkerclient.h"

WebWorker* TestWebWorkerHelper::CreateWebWorker(WebWorkerClient* client) {
  TestWebWorkerHelper* loader = new TestWebWorkerHelper();
  return loader->CreateWebWorker_(client, loader);
}

TestWebWorkerHelper::TestWebWorkerHelper() :
#if defined(OS_WIN)
      module_(NULL),
#endif
      CreateWebWorker_(NULL) {
  Load();
}

TestWebWorkerHelper::~TestWebWorkerHelper() {
}

bool TestWebWorkerHelper::IsMainThread() const {
  return WTF::isMainThread();
}

void TestWebWorkerHelper::DispatchToMainThread(WTF::MainThreadFunction* func,
                                               void* context) {
  return WTF::callOnMainThread(func, context);
}

void TestWebWorkerHelper::Load() {
  FilePath path;
  PathService::Get(base::DIR_EXE, &path);

#if defined(OS_WIN)
  path = path.AppendASCII("test_worker.dll");

  module_ = LoadLibrary(path.value().c_str());
  if (module_ == 0)
    return;

  CreateWebWorker_ = reinterpret_cast<CreateWebWorkerFunc>
      (GetProcAddress(module_, "CreateWebWorker"));
  if (!CreateWebWorker_) {
    FreeLibrary(module_);
    module_ = 0;
  }
#elif defined(OS_MACOSX)
  path = path.AppendASCII("test_worker.dylib");

  module_ = dlopen(path.value().c_str(), RTLD_NOW | RTLD_LOCAL);
  if (!module_)
    return;

  CreateWebWorker_ = reinterpret_cast<CreateWebWorkerFunc>
      (dlsym(module_, "CreateWebWorker"));
  if (!CreateWebWorker_) {
    dlclose(module_);
    module_ = 0;
  }
#else
  NOTIMPLEMENTED();
#endif
}

void TestWebWorkerHelper::Unload() {
  // Since this is called from DLL, delay the unloading until it can be
  // invoked from EXE.
  return WTF::callOnMainThread(UnloadHelper, this);
}

void TestWebWorkerHelper::UnloadHelper(void* param) {
  TestWebWorkerHelper* this_ptr = static_cast<TestWebWorkerHelper*>(param);

#if defined(OS_WIN)
  if (this_ptr->module_) {
    FreeLibrary(this_ptr->module_);
    this_ptr->module_ = 0;
  }
#else
  NOTIMPLEMENTED();
#endif

  delete this_ptr;
}
<commit_msg><commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"
#include <wtf/MainThread.h>
#include <wtf/Threading.h>
#undef LOG

#include "build/build_config.h"

#include "webkit/tools/test_shell/test_webworker_helper.h"

#if defined(OS_MACOSX)
#include <dlfcn.h>
#endif

#include "base/logging.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "third_party/WebKit/WebKit/chromium/public/WebKit.h"
#include "webkit/glue/webworkerclient.h"

WebWorker* TestWebWorkerHelper::CreateWebWorker(WebWorkerClient* client) {
  TestWebWorkerHelper* loader = new TestWebWorkerHelper();
  return loader->CreateWebWorker_(client, loader);
}

TestWebWorkerHelper::TestWebWorkerHelper() :
#if defined(OS_WIN)
      module_(NULL),
#endif
      CreateWebWorker_(NULL) {
  Load();
}

TestWebWorkerHelper::~TestWebWorkerHelper() {
}

bool TestWebWorkerHelper::IsMainThread() const {
  return WTF::isMainThread();
}

void TestWebWorkerHelper::DispatchToMainThread(WTF::MainThreadFunction* func,
                                               void* context) {
  return WTF::callOnMainThread(func, context);
}

void TestWebWorkerHelper::Load() {
  FilePath path;
  PathService::Get(base::DIR_EXE, &path);

#if defined(OS_WIN)
  path = path.AppendASCII("test_worker.dll");

  module_ = LoadLibrary(path.value().c_str());
  if (module_ == 0)
    return;

  CreateWebWorker_ = reinterpret_cast<CreateWebWorkerFunc>
      (GetProcAddress(module_, "CreateWebWorker"));
  if (!CreateWebWorker_) {
    FreeLibrary(module_);
    module_ = 0;
  }
#elif defined(OS_MACOSX)
  path = path.AppendASCII("test_worker.dylib");

  module_ = dlopen(path.value().c_str(), RTLD_NOW | RTLD_LOCAL);
  if (!module_)
    return;

  CreateWebWorker_ = reinterpret_cast<CreateWebWorkerFunc>
      (dlsym(module_, "CreateWebWorker"));
  if (!CreateWebWorker_) {
    dlclose(module_);
    module_ = 0;
  }
#else
  NOTIMPLEMENTED();
#endif
}

void TestWebWorkerHelper::Unload() {
  // Since this is called from DLL, delay the unloading until it can be
  // invoked from EXE.
  return WTF::callOnMainThread(UnloadHelper, this);
}

void TestWebWorkerHelper::UnloadHelper(void* param) {
  TestWebWorkerHelper* this_ptr = static_cast<TestWebWorkerHelper*>(param);

#if defined(OS_WIN)
  if (this_ptr->module_) {
    FreeLibrary(this_ptr->module_);
    this_ptr->module_ = 0;
  }
#elif defined(OS_MACOSX)
  if (this_ptr->module_) {
    dlclose(this_ptr->module_);
    this_ptr->module_ = 0;
    this_ptr->CreateWebWorker_ = 0;
  }
#else
  NOTIMPLEMENTED();
#endif

  delete this_ptr;
}
<|endoftext|>


<commit_before>/*
 * common.cpp -- Blackmagic Design DeckLink common functions
 * Copyright (C) 2012 Dan Dennedy <dan@dennedy.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with consumer library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "common.h"
#include <stdlib.h>
#include <unistd.h>

#ifdef __DARWIN__

char* getCString( DLString aDLString )
{
	char* CString = (char*) malloc( 64 );
	CFStringGetCString( aDLString, CString, 64, kCFStringEncodingMacRoman );
	return CString;
}

void freeCString( char* aCString )
{
	if ( aCString ) free( aCString );
}

void freeDLString( DLString aDLString )
{
	if ( aDLString ) CFRelease( aDLString );
}

#elif defined(WIN32)

char* getCString( DLString aDLString )
{
	char* CString = NULL;
	if ( aDLString )
	{
		int size = WideCharToMultiByte( CP_UTF8, 0, aDLString, -1, NULL, 0, NULL, NULL );
		if (size)
		{
			CString = new char[ size ];
			size = WideCharToMultiByte( CP_UTF8, 0, aDLString, -1, CString, size, NULL, NULL );
			if ( !size )
			{
				delete[] CString;
				CString = NULL;
			}
		}
	}
	return CString;
}

void freeCString( char* aCString )
{
	delete[] aCString;
}

void freeDLString( DLString aDLString )
{
	if ( aDLString ) free( (void*) aDLString );
}

#else

char* getCString( DLString aDLString )
{
	return aDLString? (char*) aDLString : NULL;
}

void freeCString( char* aCString )
{
}

void freeDLString( DLString aDLString )
{
	if ( aDLString ) free( (void*) aDLString );
}

#endif

void swab2( const void *from, void *to, int n )
{
#if defined(USE_SSE)
#define SWAB_STEP 16
	__asm__ volatile
	(
		"loop_start:                            \n\t"

		/* load */
		"movdqa         0(%[from]), %%xmm0      \n\t"
		"add            $0x10, %[from]          \n\t"

		/* duplicate to temp registers */
		"movdqa         %%xmm0, %%xmm1          \n\t"

		/* shift right temp register */
		"psrlw          $8, %%xmm1              \n\t"

		/* shift left main register */
		"psllw          $8, %%xmm0              \n\t"

		/* compose them back */
		"por           %%xmm0, %%xmm1           \n\t"

		/* save */
		"movdqa         %%xmm1, 0(%[to])        \n\t"
		"add            $0x10, %[to]            \n\t"

		"dec            %[cnt]                  \n\t"
		"jnz            loop_start              \n\t"

		:
		: [from]"r"(from), [to]"r"(to), [cnt]"r"(n / SWAB_STEP)
		//: "xmm0", "xmm1"
	);

	from = (unsigned char*) from + n - (n % SWAB_STEP);
	to = (unsigned char*) to + n - (n % SWAB_STEP);
	n = (n % SWAB_STEP);
#endif
	swab(from, to, n);
};
<commit_msg>Fix compile error on Windows.<commit_after>/*
 * common.cpp -- Blackmagic Design DeckLink common functions
 * Copyright (C) 2012 Dan Dennedy <dan@dennedy.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with consumer library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "common.h"
#include <stdlib.h>
#include <unistd.h>

#ifdef __DARWIN__

char* getCString( DLString aDLString )
{
	char* CString = (char*) malloc( 64 );
	CFStringGetCString( aDLString, CString, 64, kCFStringEncodingMacRoman );
	return CString;
}

void freeCString( char* aCString )
{
	if ( aCString ) free( aCString );
}

void freeDLString( DLString aDLString )
{
	if ( aDLString ) CFRelease( aDLString );
}

#elif defined(WIN32)

char* getCString( DLString aDLString )
{
	char* CString = NULL;
	if ( aDLString )
	{
		int size = WideCharToMultiByte( CP_UTF8, 0, aDLString, -1, NULL, 0, NULL, NULL );
		if (size)
		{
			CString = new char[ size ];
			size = WideCharToMultiByte( CP_UTF8, 0, aDLString, -1, CString, size, NULL, NULL );
			if ( !size )
			{
				delete[] CString;
				CString = NULL;
			}
		}
	}
	return CString;
}

void freeCString( char* aCString )
{
	delete[] aCString;
}

void freeDLString( DLString aDLString )
{
	if ( aDLString ) free( (void*) aDLString );
}

#else

char* getCString( DLString aDLString )
{
	return aDLString? (char*) aDLString : NULL;
}

void freeCString( char* aCString )
{
}

void freeDLString( DLString aDLString )
{
	if ( aDLString ) free( (void*) aDLString );
}

#endif

void swab2( const void *from, void *to, int n )
{
#if defined(USE_SSE)
#define SWAB_STEP 16
	__asm__ volatile
	(
		"loop_start:                            \n\t"

		/* load */
		"movdqa         0(%[from]), %%xmm0      \n\t"
		"add            $0x10, %[from]          \n\t"

		/* duplicate to temp registers */
		"movdqa         %%xmm0, %%xmm1          \n\t"

		/* shift right temp register */
		"psrlw          $8, %%xmm1              \n\t"

		/* shift left main register */
		"psllw          $8, %%xmm0              \n\t"

		/* compose them back */
		"por           %%xmm0, %%xmm1           \n\t"

		/* save */
		"movdqa         %%xmm1, 0(%[to])        \n\t"
		"add            $0x10, %[to]            \n\t"

		"dec            %[cnt]                  \n\t"
		"jnz            loop_start              \n\t"

		:
		: [from]"r"(from), [to]"r"(to), [cnt]"r"(n / SWAB_STEP)
		//: "xmm0", "xmm1"
	);

	from = (unsigned char*) from + n - (n % SWAB_STEP);
	to = (unsigned char*) to + n - (n % SWAB_STEP);
	n = (n % SWAB_STEP);
#endif
	swab((char*) from, (char*) to, n);
};
<|endoftext|>


<commit_before><commit_msg>Remove some android support code which isnt needed because this is build into SDL2<commit_after><|endoftext|>


<commit_before>/* Copyright (C) 2013 Slawomir Cygan <slawomir.cygan@gmail.com>
*
* 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.
*/

// dllmain.cpp : Defines the entry point for the DLL application.

#include "api-loader.h"
#include "debugger.h"
#include "ipc.h"
#include "globalstate.h"
#include "exechook.h"
#include "dl-intercept.h"
#include "DGLWrapper.h"
#include <boost/make_shared.hpp>
#include <boost/interprocess/sync/named_semaphore.hpp>

#ifdef USE_DETOURS
#include "detours/detours.h"
#endif

#include <DGLCommon/os.h>
#include <atomic>
#include <thread>
#include <condition_variable>

DGLIPC* getIPC() {
    static std::shared_ptr<DGLIPC> s_IPC;

    if (!s_IPC.get()) {
        s_IPC = DGLIPC::CreateFromUUID(Os::getEnv("dgl_uuid"));
    }

    return s_IPC.get();
}

/**
 * DGLwrapper routine called on library load
 */
void Initialize(void) {

    // catch all CreateProcess calls on Windows
    ExecHookInitialize();

    //Catch all LoadLibrary calls on Windows
    DLIntercept::initialize();

    //Notify process skipper (for newly executed processes).
    getIPC()->newProcessNotify();

    APILoader& apiLoader = EarlyGlobalState::getApiLoader();

    // load system GL libraries (& initialize entrypoint tables)

    // loads are lazy - may be defferred until application loads them.
    //This to avoid loader deadlocks/crashes.
    bool useEGL = (getIPC()->getDebuggerMode() == DGLIPC::DebuggerMode::EGL);
    apiLoader.loadDefaultLibraries(useEGL, -1, APILoader::LoadMode::LAZY);
}

/**
 * DGLwrapper routine called on library unload
 */
void TearDown() { GlobalState::reset(); }

#ifndef _WIN32

void __attribute__((constructor)) DGLWrapperLoad(void) { Initialize(); }

void __attribute__((destructor)) DGLWrapperUnload(void) { TearDown(); }
#else

#include <windows.h>

#if DGL_HAVE_WA(ARM_MALI_EMU_LOADERTHREAD_KEEP)

class ThreadWatcher {
   public:
    ThreadWatcher() : m_ThreadCount() {
        m_ThreadCount = 0;

        m_NativeSemaphore = CreateSemaphore(NULL, 0, 0xffff, NULL);
        if (!m_NativeSemaphore) {
            Os::fatal(
                    "Cannot create loader semaphore (CreateSemaphore failed)");
        }
    }

    ~ThreadWatcher() {
        if (!CloseHandle(m_NativeSemaphore)) {
            Os::fatal("Cannot close loader semaphore (CloseHandle failed)");
        }
    }

    void onAttachThread() { m_ThreadCount++; }

    void onDettachThread() {
        if (std::atomic_fetch_sub(&m_ThreadCount, 1) <= 1) {
            unlockLoaderThread();
        }
    }

    void unlockLoaderThread() {
        if (!ReleaseSemaphore(m_NativeSemaphore, 1, NULL)) {
            Os::fatal("Cannot unlock loader thread (ReleaseSemaphore failed)");
        }
    }

    void lockLoaderThread() {
        if (WaitForSingleObject(m_NativeSemaphore, INFINITE) != WAIT_OBJECT_0) {
            Os::fatal(
                    "Cannot loack loader thread (WaitForSingleObject failed)");
        }
    }

   private:
    HANDLE m_NativeSemaphore;
    std::atomic_int m_ThreadCount;
} g_ThreadWatcher;
#endif

/**
 * DGLwrapper routine called just after DLLinjection
 */
extern "C" DGLWRAPPER_API void LoaderThread() {

    int i = 1;
    while (i) {}

    Initialize();

#if DGL_HAVE_WA(ARM_MALI_EMU_LOADERTHREAD_KEEP)
    // this is called from remotely created thread started right after dll
    // injection

    // Workaround for ARM Mali OpenGL ES wrapper on Windows:
    // do not exit remote loader thread before app tear down
    //  Normally we would just return from this (empty) function causing loader
    //  thread to exit (leaving app in suspended state - no user threads).
    //  This would also cause DLL_THREAD_DETACH on all recently loaded DLLs.
    // Unfortunately
    //  this causes CreateWindowEx() to fail later in eglInitialize(), propably
    // because
    //  RegisterClass was called in this thread (sic!) from DLLMain.
    // Fix: lock this thread until application finishes

    // tell the loader we are done, so it can resume application
    getIPC()->postRemoteThreadSemaphore();

    // wait for application exit (all threads but this exit);
    g_ThreadWatcher.lockLoaderThread();
#endif
}

/**
 * Main entrypoint of DGLwrapper library
 */
BOOL APIENTRY
DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/
        ) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
#ifdef USE_DETOURS
            if (DetourIsHelperProcess()) {
                return TRUE;
            }
#endif
            Os::setCurrentModuleHandle(hModule);
            break;
        case DLL_THREAD_ATTACH:
#if DGL_HAVE_WA(ARM_MALI_EMU_LOADERTHREAD_KEEP)
            g_ThreadWatcher.onAttachThread();
#endif
            break;
        case DLL_THREAD_DETACH:
#if DGL_HAVE_WA(ARM_MALI_EMU_LOADERTHREAD_KEEP)
            g_ThreadWatcher.onDettachThread();
#endif
            break;
        case DLL_PROCESS_DETACH:
            TearDown();
            break;
    }
    return TRUE;
}

#endif
<commit_msg>Accidentally comitted "the breakpoint of all debugging" :)<commit_after>/* Copyright (C) 2013 Slawomir Cygan <slawomir.cygan@gmail.com>
*
* 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.
*/

// dllmain.cpp : Defines the entry point for the DLL application.

#include "api-loader.h"
#include "debugger.h"
#include "ipc.h"
#include "globalstate.h"
#include "exechook.h"
#include "dl-intercept.h"
#include "DGLWrapper.h"
#include <boost/make_shared.hpp>
#include <boost/interprocess/sync/named_semaphore.hpp>

#ifdef USE_DETOURS
#include "detours/detours.h"
#endif

#include <DGLCommon/os.h>
#include <atomic>
#include <thread>
#include <condition_variable>

DGLIPC* getIPC() {
    static std::shared_ptr<DGLIPC> s_IPC;

    if (!s_IPC.get()) {
        s_IPC = DGLIPC::CreateFromUUID(Os::getEnv("dgl_uuid"));
    }

    return s_IPC.get();
}

/**
 * DGLwrapper routine called on library load
 */
void Initialize(void) {

    // catch all CreateProcess calls on Windows
    ExecHookInitialize();

    //Catch all LoadLibrary calls on Windows
    DLIntercept::initialize();

    //Notify process skipper (for newly executed processes).
    getIPC()->newProcessNotify();

    APILoader& apiLoader = EarlyGlobalState::getApiLoader();

    // load system GL libraries (& initialize entrypoint tables)

    // loads are lazy - may be defferred until application loads them.
    //This to avoid loader deadlocks/crashes.
    bool useEGL = (getIPC()->getDebuggerMode() == DGLIPC::DebuggerMode::EGL);
    apiLoader.loadDefaultLibraries(useEGL, -1, APILoader::LoadMode::LAZY);
}

/**
 * DGLwrapper routine called on library unload
 */
void TearDown() { GlobalState::reset(); }

#ifndef _WIN32

void __attribute__((constructor)) DGLWrapperLoad(void) { Initialize(); }

void __attribute__((destructor)) DGLWrapperUnload(void) { TearDown(); }
#else

#include <windows.h>

#if DGL_HAVE_WA(ARM_MALI_EMU_LOADERTHREAD_KEEP)

class ThreadWatcher {
   public:
    ThreadWatcher() : m_ThreadCount() {
        m_ThreadCount = 0;

        m_NativeSemaphore = CreateSemaphore(NULL, 0, 0xffff, NULL);
        if (!m_NativeSemaphore) {
            Os::fatal(
                    "Cannot create loader semaphore (CreateSemaphore failed)");
        }
    }

    ~ThreadWatcher() {
        if (!CloseHandle(m_NativeSemaphore)) {
            Os::fatal("Cannot close loader semaphore (CloseHandle failed)");
        }
    }

    void onAttachThread() { m_ThreadCount++; }

    void onDettachThread() {
        if (std::atomic_fetch_sub(&m_ThreadCount, 1) <= 1) {
            unlockLoaderThread();
        }
    }

    void unlockLoaderThread() {
        if (!ReleaseSemaphore(m_NativeSemaphore, 1, NULL)) {
            Os::fatal("Cannot unlock loader thread (ReleaseSemaphore failed)");
        }
    }

    void lockLoaderThread() {
        if (WaitForSingleObject(m_NativeSemaphore, INFINITE) != WAIT_OBJECT_0) {
            Os::fatal(
                    "Cannot loack loader thread (WaitForSingleObject failed)");
        }
    }

   private:
    HANDLE m_NativeSemaphore;
    std::atomic_int m_ThreadCount;
} g_ThreadWatcher;
#endif

/**
 * DGLwrapper routine called just after DLLinjection
 */
extern "C" DGLWRAPPER_API void LoaderThread() {

    Initialize();

#if DGL_HAVE_WA(ARM_MALI_EMU_LOADERTHREAD_KEEP)
    // this is called from remotely created thread started right after dll
    // injection

    // Workaround for ARM Mali OpenGL ES wrapper on Windows:
    // do not exit remote loader thread before app tear down
    //  Normally we would just return from this (empty) function causing loader
    //  thread to exit (leaving app in suspended state - no user threads).
    //  This would also cause DLL_THREAD_DETACH on all recently loaded DLLs.
    // Unfortunately
    //  this causes CreateWindowEx() to fail later in eglInitialize(), propably
    // because
    //  RegisterClass was called in this thread (sic!) from DLLMain.
    // Fix: lock this thread until application finishes

    // tell the loader we are done, so it can resume application
    getIPC()->postRemoteThreadSemaphore();

    // wait for application exit (all threads but this exit);
    g_ThreadWatcher.lockLoaderThread();
#endif
}

/**
 * Main entrypoint of DGLwrapper library
 */
BOOL APIENTRY
DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/
        ) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
#ifdef USE_DETOURS
            if (DetourIsHelperProcess()) {
                return TRUE;
            }
#endif
            Os::setCurrentModuleHandle(hModule);
            break;
        case DLL_THREAD_ATTACH:
#if DGL_HAVE_WA(ARM_MALI_EMU_LOADERTHREAD_KEEP)
            g_ThreadWatcher.onAttachThread();
#endif
            break;
        case DLL_THREAD_DETACH:
#if DGL_HAVE_WA(ARM_MALI_EMU_LOADERTHREAD_KEEP)
            g_ThreadWatcher.onDettachThread();
#endif
            break;
        case DLL_PROCESS_DETACH:
            TearDown();
            break;
    }
    return TRUE;
}

#endif
<|endoftext|>