Sharing for buffer, texture and renderbuffer objects.

TRAC #12496 Derive Renderbuffer, Texture and Buffer from RefCountObject. This class keeps a reference count for all objects that need cross-context reference counting, and also the object id. Restructure Renderbuffers to create a wrapper object and a storage object. Use BindingPointer for all binding points instead of binding by object id. Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch git-svn-id: https://angleproject.googlecode.com/svn/trunk@364 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 0d25b005
......@@ -186,6 +186,8 @@
'libGLESv2/mathutil.h',
'libGLESv2/Program.cpp',
'libGLESv2/Program.h',
'libGLESv2/RefCountObject.cpp',
'libGLESv2/RefCountObject.h',
'libGLESv2/Renderbuffer.cpp',
'libGLESv2/Renderbuffer.h',
'libGLESv2/Shader.cpp',
......
......@@ -13,7 +13,7 @@
namespace gl
{
Buffer::Buffer()
Buffer::Buffer(GLuint id) : RefCountObject(id)
{
mContents = NULL;
mSize = 0;
......
......@@ -18,14 +18,15 @@
#include <GLES2/gl2.h>
#include "common/angleutils.h"
#include "libGLESv2/RefCountObject.h"
namespace gl
{
class Buffer
class Buffer : public RefCountObject
{
public:
Buffer();
explicit Buffer(GLuint id);
virtual ~Buffer();
......
......@@ -20,6 +20,7 @@
#include "common/angleutils.h"
#include "libGLESv2/ResourceManager.h"
#include "libGLESv2/RefCountObject.h"
namespace egl
{
......@@ -41,6 +42,7 @@ class Texture2D;
class TextureCubeMap;
class Framebuffer;
class Renderbuffer;
class RenderbufferStorage;
class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
......@@ -85,7 +87,7 @@ class AttributeState
{
public:
AttributeState()
: mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mBoundBuffer(0), mEnabled(false)
: mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mEnabled(false)
{
mCurrentValue[0] = 0;
mCurrentValue[1] = 0;
......@@ -100,7 +102,7 @@ class AttributeState
GLsizei mStride; // 0 means natural stride
const void *mPointer;
GLuint mBoundBuffer; // Captured when VertexArrayPointer is called.
BindingPointer<Buffer> mBoundBuffer; // Captured when VertexArrayPointer is called.
bool mEnabled; // From Enable/DisableVertexAttribArray
......@@ -175,16 +177,16 @@ struct State
bool depthMask;
int activeSampler; // Active texture unit selector - GL_TEXTURE0
GLuint arrayBuffer;
GLuint elementArrayBuffer;
GLuint texture2D;
GLuint textureCubeMap;
BindingPointer<Buffer> arrayBuffer;
BindingPointer<Buffer> elementArrayBuffer;
BindingPointer<Texture> texture2D;
BindingPointer<Texture> textureCubeMap;
GLuint framebuffer;
GLuint renderbuffer;
BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
GLuint samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
GLint unpackAlignment;
GLint packAlignment;
......@@ -278,7 +280,7 @@ class Context
void setVertexAttribEnabled(unsigned int attribNum, bool enabled);
const AttributeState &getVertexAttribState(unsigned int attribNum);
void setVertexAttribState(unsigned int attribNum, GLuint boundBuffer, GLint size, GLenum type,
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
......@@ -303,7 +305,7 @@ class Context
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
void deleteRenderbuffer(GLuint renderbuffer);
// Framebuffers are owned by the Context, so these methods do not pass through
GLuint createFramebuffer();
void deleteFramebuffer(GLuint framebuffer);
......@@ -317,9 +319,8 @@ class Context
void useProgram(GLuint program);
void setFramebufferZero(Framebuffer *framebuffer);
void setColorbufferZero(Colorbuffer *renderbuffer);
void setDepthStencilbufferZero(DepthStencilbuffer *depthStencilBuffer);
void setRenderbuffer(Renderbuffer *renderbuffer);
void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
void setVertexAttrib(GLuint index, const GLfloat *values);
......@@ -329,9 +330,6 @@ class Context
Texture *getTexture(GLuint handle);
Framebuffer *getFramebuffer(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
Colorbuffer *getColorbuffer(GLuint handle);
DepthStencilbuffer *getDepthbuffer(GLuint handle);
DepthStencilbuffer *getStencilbuffer(GLuint handle);
Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer();
......
......@@ -15,9 +15,11 @@
#include <d3d9.h>
#include "common/angleutils.h"
#include "libGLESv2/RefCountObject.h"
namespace gl
{
class Renderbuffer;
class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
......@@ -26,9 +28,9 @@ class DepthStencilbuffer;
class Framebuffer
{
public:
explicit Framebuffer(GLuint handle);
Framebuffer();
~Framebuffer();
virtual ~Framebuffer();
void setColorbuffer(GLenum type, GLuint colorbuffer);
void setDepthbuffer(GLenum type, GLuint depthbuffer);
......@@ -55,22 +57,35 @@ class Framebuffer
GLuint getDepthbufferHandle();
GLuint getStencilbufferHandle();
GLenum completeness();
virtual GLenum completeness();
private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
GLuint mColorbufferHandle;
protected:
GLenum mColorbufferType;
BindingPointer<Renderbuffer> mColorbufferPointer;
GLuint mDepthbufferHandle;
GLenum mDepthbufferType;
BindingPointer<Renderbuffer> mDepthbufferPointer;
GLuint mStencilbufferHandle;
GLenum mStencilbufferType;
BindingPointer<Renderbuffer> mStencilbufferPointer;
private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
};
class DefaultFramebuffer : public Framebuffer
{
public:
DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil);
GLuint mHandle;
virtual GLenum completeness();
private:
DISALLOW_COPY_AND_ASSIGN(DefaultFramebuffer);
};
}
#endif // LIBGLESV2_FRAMEBUFFER_H_
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RefCountObject.cpp: Defines the gl::RefCountObject base class that provides
// lifecycle support for GL objects using the traditional BindObject scheme, but
// that need to be reference counted for correct cross-context deletion.
// (Concretely, textures, buffers and renderbuffers.)
#include "RefCountObject.h"
namespace gl
{
RefCountObject::RefCountObject(GLuint id)
{
mId = id;
mRefCount = 0;
}
RefCountObject::~RefCountObject()
{
}
void RefCountObject::addRef() const
{
mRefCount++;
}
void RefCountObject::release() const
{
ASSERT(mRefCount > 0);
if (--mRefCount == 0)
{
delete this;
}
}
void RefCountObjectBindingPointer::set(RefCountObject *newObject)
{
// addRef first in case newObject == mObject and this is the last reference to it.
if (newObject != NULL) newObject->addRef();
if (mObject != NULL) mObject->release();
mObject = newObject;
}
}
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RefCountObject.h: Defines the gl::RefCountObject base class that provides
// lifecycle support for GL objects using the traditional BindObject scheme, but
// that need to be reference counted for correct cross-context deletion.
// (Concretely, textures, buffers and renderbuffers.)
#ifndef LIBGLESV2_REFCOUNTOBJECT_H_
#define LIBGLESV2_REFCOUNTOBJECT_H_
#include <cstddef>
#define GL_APICALL
#include <GLES2/gl2.h>
#include "common/debug.h"
namespace gl
{
class RefCountObject
{
public:
explicit RefCountObject(GLuint id);
virtual ~RefCountObject();
virtual void addRef() const;
virtual void release() const;
GLuint id() const { return mId; }
private:
GLuint mId;
mutable std::size_t mRefCount;
};
class RefCountObjectBindingPointer
{
protected:
RefCountObjectBindingPointer() : mObject(NULL) { }
~RefCountObjectBindingPointer() { ASSERT(mObject == NULL); } // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up.
void set(RefCountObject *newObject);
RefCountObject *get() const { return mObject; }
public:
GLuint id() const { return (mObject != NULL) ? mObject->id() : 0; }
bool operator ! () const { return (get() == NULL); }
private:
RefCountObject *mObject;
};
template <class ObjectType>
class BindingPointer : public RefCountObjectBindingPointer
{
public:
void set(ObjectType *newObject) { RefCountObjectBindingPointer::set(newObject); }
ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
ObjectType *operator -> () const { return get(); }
};
}
#endif // LIBGLESV2_REFCOUNTOBJECT_H_
......@@ -15,73 +15,133 @@
namespace gl
{
unsigned int Renderbuffer::mCurrentSerial = 1;
unsigned int RenderbufferStorage::mCurrentSerial = 1;
Renderbuffer::Renderbuffer()
Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id)
{
mWidth = 0;
mHeight = 0;
mFormat = GL_RGBA4; // default format, needs to be one of the expected renderbuffer formats
mSerial = issueSerial();
ASSERT(storage != NULL);
mStorage = storage;
}
Renderbuffer::~Renderbuffer()
{
delete mStorage;
}
bool Renderbuffer::isColorbuffer() const
{
return mStorage->isColorbuffer();
}
bool Renderbuffer::isDepthbuffer() const
{
return mStorage->isDepthbuffer();
}
bool Renderbuffer::isColorbuffer()
bool Renderbuffer::isStencilbuffer() const
{
return mStorage->isStencilbuffer();
}
IDirect3DSurface9 *Renderbuffer::getRenderTarget()
{
return mStorage->getRenderTarget();
}
IDirect3DSurface9 *Renderbuffer::getDepthStencil()
{
return mStorage->getDepthStencil();
}
int Renderbuffer::getWidth() const
{
return mStorage->getWidth();
}
int Renderbuffer::getHeight() const
{
return mStorage->getHeight();
}
GLenum Renderbuffer::getFormat() const
{
return mStorage->getFormat();
}
unsigned int Renderbuffer::getSerial() const
{
return mStorage->getSerial();
}
void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
{
ASSERT(newStorage != NULL);
delete mStorage;
mStorage = newStorage;
}
RenderbufferStorage::RenderbufferStorage()
{
mSerial = issueSerial();
}
RenderbufferStorage::~RenderbufferStorage()
{
}
bool RenderbufferStorage::isColorbuffer() const
{
return false;
}
bool Renderbuffer::isDepthbuffer()
bool RenderbufferStorage::isDepthbuffer() const
{
return false;
}
bool Renderbuffer::isStencilbuffer()
bool RenderbufferStorage::isStencilbuffer() const
{
return false;
}
IDirect3DSurface9 *Renderbuffer::getRenderTarget()
IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
{
return NULL;
}
IDirect3DSurface9 *Renderbuffer::getDepthStencil()
IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
{
return NULL;
}
int Renderbuffer::getWidth()
int RenderbufferStorage::getWidth() const
{
return mWidth;
}
int Renderbuffer::getHeight()
int RenderbufferStorage::getHeight() const
{
return mHeight;
}
void Renderbuffer::setSize(int width, int height)
void RenderbufferStorage::setSize(int width, int height)
{
mWidth = width;
mHeight = height;
}
GLenum Renderbuffer::getFormat()
GLenum RenderbufferStorage::getFormat() const
{
return mFormat;
}
unsigned int Renderbuffer::getSerial() const
unsigned int RenderbufferStorage::getSerial() const
{
return mSerial;
}
unsigned int Renderbuffer::issueSerial()
unsigned int RenderbufferStorage::issueSerial()
{
return mCurrentSerial++;
}
......@@ -105,17 +165,21 @@ Colorbuffer::Colorbuffer(int width, int height, GLenum format)
IDirect3DDevice9 *device = getDevice();
mRenderTarget = NULL;
HRESULT result = device->CreateRenderTarget(width, height, es2dx::ConvertRenderbufferFormat(format),
D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
if (width > 0 && height > 0)
{
error(GL_OUT_OF_MEMORY);
HRESULT result = device->CreateRenderTarget(width, height, es2dx::ConvertRenderbufferFormat(format),
D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
return;
}
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
error(GL_OUT_OF_MEMORY);
ASSERT(SUCCEEDED(result));
return;
}
ASSERT(SUCCEEDED(result));
}
if (mRenderTarget)
{
......@@ -137,12 +201,12 @@ Colorbuffer::~Colorbuffer()
}
}
bool Colorbuffer::isColorbuffer()
bool Colorbuffer::isColorbuffer() const
{
return true;
}
GLuint Colorbuffer::getRedSize()
GLuint Colorbuffer::getRedSize() const
{
if (mRenderTarget)
{
......@@ -155,7 +219,7 @@ GLuint Colorbuffer::getRedSize()
return 0;
}
GLuint Colorbuffer::getGreenSize()
GLuint Colorbuffer::getGreenSize() const
{
if (mRenderTarget)
{
......@@ -168,7 +232,7 @@ GLuint Colorbuffer::getGreenSize()
return 0;
}
GLuint Colorbuffer::getBlueSize()
GLuint Colorbuffer::getBlueSize() const
{
if (mRenderTarget)
{
......@@ -181,7 +245,7 @@ GLuint Colorbuffer::getBlueSize()
return 0;
}
GLuint Colorbuffer::getAlphaSize()
GLuint Colorbuffer::getAlphaSize() const
{
if (mRenderTarget)
{
......@@ -249,17 +313,17 @@ DepthStencilbuffer::~DepthStencilbuffer()
}
}
bool DepthStencilbuffer::isDepthbuffer()
bool DepthStencilbuffer::isDepthbuffer() const
{
return true;
}
bool DepthStencilbuffer::isStencilbuffer()
bool DepthStencilbuffer::isStencilbuffer() const
{
return true;
}
GLuint DepthStencilbuffer::getDepthSize()
GLuint DepthStencilbuffer::getDepthSize() const
{
if (mDepthStencil)
{
......@@ -272,7 +336,7 @@ GLuint DepthStencilbuffer::getDepthSize()
return 0;
}
GLuint DepthStencilbuffer::getStencilSize()
GLuint DepthStencilbuffer::getStencilSize() const
{
if (mDepthStencil)
{
......@@ -314,12 +378,12 @@ Depthbuffer::~Depthbuffer()
{
}
bool Depthbuffer::isDepthbuffer()
bool Depthbuffer::isDepthbuffer() const
{
return true;
}
bool Depthbuffer::isStencilbuffer()
bool Depthbuffer::isStencilbuffer() const
{
return false;
}
......@@ -352,12 +416,12 @@ Stencilbuffer::~Stencilbuffer()
{
}
bool Stencilbuffer::isDepthbuffer()
bool Stencilbuffer::isDepthbuffer() const
{
return false;
}
bool Stencilbuffer::isStencilbuffer()
bool Stencilbuffer::isStencilbuffer() const
{
return true;
}
......
......@@ -4,8 +4,9 @@
// found in the LICENSE file.
//
// Renderbuffer.h: Defines the virtual gl::Renderbuffer class and its derived
// classes Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the
// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
#ifndef LIBGLESV2_RENDERBUFFER_H_
......@@ -16,26 +17,31 @@
#include <d3d9.h>
#include "common/angleutils.h"
#include "libGLESv2/RefCountObject.h"
namespace gl
{
class Renderbuffer
// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
// is called. The specific concrete type depends on whether the internal format is
// colour depth, stencil or packed depth/stencil.
class RenderbufferStorage
{
public:
Renderbuffer();
RenderbufferStorage();
virtual ~Renderbuffer();
virtual ~RenderbufferStorage() = 0;
virtual bool isColorbuffer();
virtual bool isDepthbuffer();
virtual bool isStencilbuffer();
virtual bool isColorbuffer() const;
virtual bool isDepthbuffer() const;
virtual bool isStencilbuffer() const;
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
virtual int getWidth();
virtual int getHeight();
GLenum getFormat();
virtual int getWidth() const;
virtual int getHeight() const;
GLenum getFormat() const;
unsigned int getSerial() const;
static unsigned int issueSerial();
......@@ -46,7 +52,7 @@ class Renderbuffer
unsigned int mSerial;
private:
DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
static unsigned int mCurrentSerial;
......@@ -54,7 +60,38 @@ class Renderbuffer
int mHeight;
};
class Colorbuffer : public Renderbuffer
// Renderbuffer implements the GL renderbuffer object.
// It's only a wrapper for a RenderbufferStorage, but the internal object
// can change whenever glRenderbufferStorage is called.
class Renderbuffer : public RefCountObject
{
public:
Renderbuffer(GLuint id, RenderbufferStorage *storage);
~Renderbuffer();
bool isColorbuffer() const;
bool isDepthbuffer() const;
bool isStencilbuffer() const;
IDirect3DSurface9 *getRenderTarget();
IDirect3DSurface9 *getDepthStencil();
int getWidth() const;
int getHeight() const;
GLenum getFormat() const;
unsigned int getSerial() const;
void setStorage(RenderbufferStorage *newStorage);
RenderbufferStorage *getStorage() { return mStorage; }
private:
DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
RenderbufferStorage *mStorage;
};
class Colorbuffer : public RenderbufferStorage
{
public:
explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
......@@ -62,12 +99,12 @@ class Colorbuffer : public Renderbuffer
~Colorbuffer();
bool isColorbuffer();
bool isColorbuffer() const;
GLuint getRedSize();
GLuint getGreenSize();
GLuint getBlueSize();
GLuint getAlphaSize();
GLuint getRedSize() const;
GLuint getGreenSize() const;
GLuint getBlueSize() const;
GLuint getAlphaSize() const;
IDirect3DSurface9 *getRenderTarget();
......@@ -78,7 +115,7 @@ class Colorbuffer : public Renderbuffer
DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
};
class DepthStencilbuffer : public Renderbuffer
class DepthStencilbuffer : public RenderbufferStorage
{
public:
explicit DepthStencilbuffer(IDirect3DSurface9 *depthStencil);
......@@ -86,11 +123,11 @@ class DepthStencilbuffer : public Renderbuffer
~DepthStencilbuffer();
virtual bool isDepthbuffer();
virtual bool isStencilbuffer();
virtual bool isDepthbuffer() const;
virtual bool isStencilbuffer() const;
GLuint getDepthSize();
GLuint getStencilSize();
GLuint getDepthSize() const;
GLuint getStencilSize() const;
IDirect3DSurface9 *getDepthStencil();
......@@ -107,8 +144,8 @@ class Depthbuffer : public DepthStencilbuffer
~Depthbuffer();
bool isDepthbuffer();
bool isStencilbuffer();
bool isDepthbuffer() const;
bool isStencilbuffer() const;
private:
DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
......@@ -122,8 +159,8 @@ class Stencilbuffer : public DepthStencilbuffer
~Stencilbuffer();
bool isDepthbuffer();
bool isStencilbuffer();
bool isDepthbuffer() const;
bool isStencilbuffer() const;
private:
DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
......
......@@ -146,14 +146,13 @@ GLuint ResourceManager::createRenderbuffer()
return handle;
}
// FIXME: shared object deletion needs handling
void ResourceManager::deleteBuffer(GLuint buffer)
{
BufferMap::iterator bufferObject = mBufferMap.find(buffer);
if (bufferObject != mBufferMap.end())
{
delete bufferObject->second;
if (bufferObject->second) bufferObject->second->release();
mBufferMap.erase(bufferObject);
}
}
......@@ -194,30 +193,24 @@ void ResourceManager::deleteProgram(GLuint program)
}
}
// FIXME: shared object deletion needs handling
void ResourceManager::deleteTexture(GLuint texture)
{
TextureMap::iterator textureObject = mTextureMap.find(texture);
if (textureObject != mTextureMap.end())
{
if (texture != 0)
{
delete textureObject->second;
}
if (textureObject->second) textureObject->second->release();
mTextureMap.erase(textureObject);
}
}
// FIXME: shared object deletion needs handling
void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
{
RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
if (renderbufferObject != mRenderbufferMap.end())
{
delete renderbufferObject->second;
if (renderbufferObject->second) renderbufferObject->second->release();
mRenderbufferMap.erase(renderbufferObject);
}
}
......@@ -303,7 +296,9 @@ void ResourceManager::checkBufferAllocation(unsigned int buffer)
{
if (buffer != 0 && !getBuffer(buffer))
{
mBufferMap[buffer] = new Buffer();
Buffer *bufferObject = new Buffer(buffer);
mBufferMap[buffer] = bufferObject;
bufferObject->addRef();
}
}
......@@ -311,14 +306,24 @@ void ResourceManager::checkTextureAllocation(GLuint texture, SamplerType type)
{
if (!getTexture(texture) && texture != 0)
{
Texture *textureObject;
if (type == SAMPLER_2D)
{
mTextureMap[texture] = new Texture2D();
textureObject = new Texture2D(texture);
}
else if (type == SAMPLER_CUBE)
{
mTextureMap[texture] = new TextureCubeMap();
textureObject = new TextureCubeMap(texture);
}
else
{
UNREACHABLE();
return;
}
mTextureMap[texture] = textureObject;
textureObject->addRef();
}
}
......@@ -326,7 +331,9 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
{
if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
{
mRenderbufferMap[renderbuffer] = new Renderbuffer();
Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4));
mRenderbufferMap[renderbuffer] = renderbufferObject;
renderbufferObject->addRef();
}
}
......
......@@ -32,7 +32,7 @@ Texture::Image::~Image()
if (surface) surface->Release();
}
Texture::Texture()
Texture::Texture(GLuint id) : RefCountObject(id)
{
mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
mMagFilter = GL_LINEAR;
......@@ -443,7 +443,7 @@ int Texture::levelCount() const
return mBaseTexture ? mBaseTexture->GetLevelCount() : 0;
}
Texture2D::Texture2D()
Texture2D::Texture2D(GLuint id) : Texture(id)
{
mTexture = NULL;
mColorbufferProxy = NULL;
......@@ -564,7 +564,7 @@ void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei widt
commitRect(level, xoffset, yoffset, width, height);
}
void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
if (redefineTexture(level, internalFormat, width, height))
{
......@@ -592,7 +592,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
mImageArray[level].format = internalFormat;
}
void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height)
{
......@@ -872,16 +872,17 @@ void Texture2D::generateMipmaps()
}
}
Colorbuffer *Texture2D::getColorbuffer(GLenum target)
Renderbuffer *Texture2D::getColorbuffer(GLenum target)
{
if (target != GL_TEXTURE_2D)
{
return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
if (mColorbufferProxy == NULL)
{
mColorbufferProxy = new TextureColorbufferProxy(this, target);
mColorbufferProxy = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
mColorbufferProxy->addRef();
}
return mColorbufferProxy;
......@@ -899,7 +900,7 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
return renderTarget;
}
TextureCubeMap::TextureCubeMap()
TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
{
mTexture = NULL;
......@@ -1279,7 +1280,7 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum internalFormat, GLsizei
return !textureOkay;
}
void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
unsigned int faceindex = faceIndex(face);
......@@ -1341,7 +1342,7 @@ IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier
return (SUCCEEDED(hr)) ? surface : NULL;
}
void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
GLsizei size = mImageArray[faceIndex(face)][level].width;
......@@ -1441,18 +1442,19 @@ void TextureCubeMap::generateMipmaps()
}
}
Colorbuffer *TextureCubeMap::getColorbuffer(GLenum target)
Renderbuffer *TextureCubeMap::getColorbuffer(GLenum target)
{
if (!IsCubemapTextureTarget(target))
{
return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
unsigned int face = faceIndex(target);
if (mFaceProxies[face] == NULL)
{
mFaceProxies[face] = new TextureColorbufferProxy(this, target);
mFaceProxies[face] = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
mFaceProxies[face]->addRef();
}
return mFaceProxies[face];
......@@ -1476,6 +1478,16 @@ Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLen
ASSERT(target == GL_TEXTURE_2D || IsCubemapTextureTarget(target));
}
void Texture::TextureColorbufferProxy::addRef() const
{
mTexture->addRef();
}
void Texture::TextureColorbufferProxy::release() const
{
mTexture->release();
}
IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget()
{
if (mRenderTarget) mRenderTarget->Release();
......@@ -1485,12 +1497,12 @@ IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget()
return mRenderTarget;
}
int Texture::TextureColorbufferProxy::getWidth()
int Texture::TextureColorbufferProxy::getWidth() const
{
return mTexture->getWidth();
}
int Texture::TextureColorbufferProxy::getHeight()
int Texture::TextureColorbufferProxy::getHeight() const
{
return mTexture->getHeight();
}
......
......@@ -33,10 +33,10 @@ enum
MAX_TEXTURE_LEVELS = 12 // 1+log2 of MAX_TEXTURE_SIZE
};
class Texture
class Texture : public RefCountObject
{
public:
explicit Texture();
explicit Texture(GLuint id);
virtual ~Texture();
......@@ -58,12 +58,14 @@ class Texture
virtual bool isComplete() const = 0;
IDirect3DBaseTexture9 *getTexture();
virtual Colorbuffer *getColorbuffer(GLenum target) = 0;
virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
virtual void generateMipmaps() = 0;
bool isDirty() const;
static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
protected:
class TextureColorbufferProxy;
friend class TextureColorbufferProxy;
......@@ -73,10 +75,13 @@ class Texture
TextureColorbufferProxy(Texture *texture, GLenum target);
// target is a 2D-like texture target (GL_TEXTURE_2D or one of the cube face targets)
virtual void addRef() const;
virtual void release() const;
virtual IDirect3DSurface9 *getRenderTarget();
virtual int getWidth();
virtual int getHeight();
virtual int getWidth() const;
virtual int getHeight() const;
private:
Texture *mTexture;
......@@ -148,7 +153,7 @@ class Texture
class Texture2D : public Texture
{
public:
explicit Texture2D();
explicit Texture2D(GLuint id);
~Texture2D();
......@@ -156,14 +161,14 @@ class Texture2D : public Texture
void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
bool isComplete() const;
virtual void generateMipmaps();
virtual Colorbuffer *getColorbuffer(GLenum target);
virtual Renderbuffer *getColorbuffer(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
......@@ -180,7 +185,7 @@ class Texture2D : public Texture
IDirect3DTexture9 *mTexture;
TextureColorbufferProxy *mColorbufferProxy;
Renderbuffer *mColorbufferProxy;
bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
......@@ -190,7 +195,7 @@ class Texture2D : public Texture
class TextureCubeMap : public Texture
{
public:
explicit TextureCubeMap();
explicit TextureCubeMap(GLuint id);
~TextureCubeMap();
......@@ -204,14 +209,14 @@ class TextureCubeMap : public Texture
void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
bool isComplete() const;
virtual void generateMipmaps();
virtual Colorbuffer *getColorbuffer(GLenum target);
virtual Renderbuffer *getColorbuffer(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
......@@ -238,7 +243,7 @@ class TextureCubeMap : public Texture
IDirect3DCubeTexture9 *mTexture;
TextureColorbufferProxy *mFaceProxies[6];
Renderbuffer *mFaceProxies[6];
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
};
......
......@@ -128,9 +128,9 @@ GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
void *output = mStreamBuffer->map(spaceRequired(attribs[i], count), &translated[i].offset);
const void *input;
if (attribs[i].mBoundBuffer)
if (attribs[i].mBoundBuffer.get())
{
Buffer *buffer = mContext->getBuffer(attribs[i].mBoundBuffer);
Buffer *buffer = attribs[i].mBoundBuffer.get();
size_t offset = reinterpret_cast<size_t>(attribs[i].mPointer);
......
......@@ -854,8 +854,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
gl::Renderbuffer *source = framebuffer->getColorbuffer();
gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
......@@ -928,8 +927,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
gl::Renderbuffer *source = framebuffer->getColorbuffer();
gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
......@@ -2520,7 +2518,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_RED_SIZE:
if (renderbuffer->isColorbuffer())
{
*params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
*params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
}
else
{
......@@ -2530,7 +2528,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_GREEN_SIZE:
if (renderbuffer->isColorbuffer())
{
*params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
*params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
}
else
{
......@@ -2540,7 +2538,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_BLUE_SIZE:
if (renderbuffer->isColorbuffer())
{
*params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
*params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
}
else
{
......@@ -2550,7 +2548,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_ALPHA_SIZE:
if (renderbuffer->isColorbuffer())
{
*params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
*params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
}
else
{
......@@ -2560,7 +2558,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_DEPTH_SIZE:
if (renderbuffer->isDepthbuffer())
{
*params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
*params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
}
else
{
......@@ -2570,7 +2568,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_STENCIL_SIZE:
if (renderbuffer->isStencilbuffer())
{
*params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
*params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
}
else
{
......@@ -3005,7 +3003,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
return error(GL_INVALID_VALUE);
}
gl::AttributeState attribState = context->getVertexAttribState(index);
const gl::AttributeState &attribState = context->getVertexAttribState(index);
switch (pname)
{
......@@ -3025,7 +3023,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
*params = (GLfloat)attribState.mBoundBuffer;
*params = (GLfloat)attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
......@@ -3058,7 +3056,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
return error(GL_INVALID_VALUE);
}
gl::AttributeState attribState = context->getVertexAttribState(index);
const gl::AttributeState &attribState = context->getVertexAttribState(index);
switch (pname)
{
......@@ -3078,7 +3076,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
*params = attribState.mBoundBuffer;
*params = attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
......@@ -3570,7 +3568,8 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
if (context)
{
if (context->getRenderbufferHandle() == 0)
GLuint handle = context->getRenderbufferHandle();
if (handle == 0)
{
return error(GL_INVALID_OPERATION);
}
......@@ -3578,18 +3577,18 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
switch (internalformat)
{
case GL_DEPTH_COMPONENT16:
context->setRenderbuffer(new gl::Depthbuffer(width, height));
context->setRenderbufferStorage(new gl::Depthbuffer(width, height));
break;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat));
break;
case GL_STENCIL_INDEX8:
context->setRenderbuffer(new gl::Stencilbuffer(width, height));
context->setRenderbufferStorage(new gl::Stencilbuffer(width, height));
break;
case GL_DEPTH24_STENCIL8_OES:
context->setRenderbuffer(new gl::DepthStencilbuffer(width, height));
context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height));
break;
default:
return error(GL_INVALID_ENUM);
......@@ -4981,7 +4980,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
if (context)
{
context->setVertexAttribState(index, context->getArrayBufferHandle(), size, type, (normalized == GL_TRUE), stride, ptr);
context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
}
}
catch(std::bad_alloc&)
......
......@@ -217,6 +217,10 @@
>
</File>
<File
RelativePath=".\RefCountObject.cpp"
>
</File>
<File
RelativePath=".\Renderbuffer.cpp"
>
</File>
......@@ -303,6 +307,10 @@
>
</File>
<File
RelativePath=".\RefCountObject.h"
>
</File>
<File
RelativePath=".\Renderbuffer.h"
>
</File>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment