зеркало из https://github.com/mozilla/gecko-dev.git
Bug 604101 - Part 5 - Use Pixel Buffer Objects in TextureImageCGL. r=joe,jrmuizel a=blocking2.0
This commit is contained in:
Родитель
63935bac8b
Коммит
41f7a4eadc
|
@ -47,7 +47,7 @@
|
|||
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLContextProvider.h"
|
||||
|
||||
|
@ -312,6 +312,11 @@ GLContext::InitWithPrefix(const char *prefix, PRBool trygl)
|
|||
{ mIsGLES2 ? (PRFuncPtr*) NULL : (PRFuncPtr*) &mSymbols.fReadBuffer,
|
||||
{ mIsGLES2 ? NULL : "ReadBuffer", NULL } },
|
||||
|
||||
{ mIsGLES2 ? (PRFuncPtr*) NULL : (PRFuncPtr*) &mSymbols.fMapBuffer,
|
||||
{ mIsGLES2 ? NULL : "MapBuffer", NULL } },
|
||||
{ mIsGLES2 ? (PRFuncPtr*) NULL : (PRFuncPtr*) &mSymbols.fUnmapBuffer,
|
||||
{ mIsGLES2 ? NULL : "UnmapBuffer", NULL } },
|
||||
|
||||
{ NULL, { NULL } },
|
||||
|
||||
};
|
||||
|
@ -321,6 +326,10 @@ GLContext::InitWithPrefix(const char *prefix, PRBool trygl)
|
|||
if (mInitialized) {
|
||||
InitExtensions();
|
||||
|
||||
NS_ASSERTION(!IsExtensionSupported(GLContext::ARB_pixel_buffer_object) ||
|
||||
(mSymbols.fMapBuffer && mSymbols.fUnmapBuffer),
|
||||
"ARB_pixel_buffer_object supported without glMapBuffer/UnmapBuffer being available!");
|
||||
|
||||
GLint v[4];
|
||||
|
||||
fGetIntegerv(LOCAL_GL_SCISSOR_BOX, v);
|
||||
|
@ -404,6 +413,7 @@ static const char *sExtensionNames[] = {
|
|||
"GL_EXT_read_format_bgra",
|
||||
"GL_APPLE_client_storage",
|
||||
"GL_ARB_texture_non_power_of_two",
|
||||
"GL_ARB_pixel_buffer_object",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -566,15 +576,22 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> updateSurface =
|
||||
CreateUpdateSurface(gfxIntSize(rgnSize.width, rgnSize.height),
|
||||
format);
|
||||
nsRefPtr<gfxASurface> updateSurface =
|
||||
GetSurfaceForUpdate(gfxIntSize(rgnSize.width, rgnSize.height), format);
|
||||
|
||||
if (!updateSurface)
|
||||
return NULL;
|
||||
|
||||
updateSurface->SetDeviceOffset(gfxPoint(-mUpdateRect.x, -mUpdateRect.y));
|
||||
|
||||
mUpdateContext = new gfxContext(updateSurface);
|
||||
|
||||
// Clear the returned surface because it might have been re-used.
|
||||
if (format == gfxASurface::ImageFormatARGB32) {
|
||||
mUpdateContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
mUpdateContext->Paint();
|
||||
mUpdateContext->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
}
|
||||
return mUpdateContext;
|
||||
}
|
||||
|
||||
|
@ -590,25 +607,44 @@ BasicTextureImage::EndUpdate()
|
|||
// but important if we ever do anything directly with the surface.
|
||||
originalSurface->SetDeviceOffset(gfxPoint(0, 0));
|
||||
|
||||
bool relative = FinishedSurfaceUpdate();
|
||||
|
||||
// The rect to upload from the surface is mUpdateRect sized and located at mUpdateOffset.
|
||||
nsIntRect surfaceRect(mUpdateOffset.x, mUpdateOffset.y, mUpdateRect.width, mUpdateRect.height);
|
||||
if (!mTextureInited) {
|
||||
surfaceRect.x = 0;
|
||||
surfaceRect.y = 0;
|
||||
}
|
||||
|
||||
mShaderType =
|
||||
mGLContext->UploadSurfaceToTexture(originalSurface,
|
||||
surfaceRect,
|
||||
mTexture,
|
||||
!mTextureInited,
|
||||
mUpdateRect.TopLeft());
|
||||
mUpdateRect.TopLeft(),
|
||||
relative);
|
||||
FinishedSurfaceUpload();
|
||||
|
||||
mUpdateContext = nsnull;
|
||||
mTextureInited = PR_TRUE;
|
||||
|
||||
return PR_TRUE; // mTexture is bound
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BasicTextureImage::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
|
||||
{
|
||||
return gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
|
||||
}
|
||||
|
||||
bool
|
||||
BasicTextureImage::FinishedSurfaceUpdate()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
BasicTextureImage::FinishedSurfaceUpload()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BasicTextureImage::Resize(const nsIntSize& aSize)
|
||||
{
|
||||
|
@ -1208,7 +1244,8 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
|||
const nsIntRect& aSrcRect,
|
||||
GLuint& aTexture,
|
||||
bool aOverwrite,
|
||||
const nsIntPoint& aDstPoint)
|
||||
const nsIntPoint& aDstPoint,
|
||||
bool aPixelBuffer)
|
||||
{
|
||||
bool textureInited = aOverwrite ? false : true;
|
||||
MakeCurrent();
|
||||
|
@ -1235,7 +1272,9 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
|||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface = aSurface->GetAsImageSurface();
|
||||
unsigned char* data;
|
||||
// If a pixel buffer is bound the data pointer parameter is relative
|
||||
// to the start of the data block.
|
||||
unsigned char* data = aPixelBuffer ? NULL : imageSurface->Data();
|
||||
|
||||
if (!imageSurface ||
|
||||
(imageSurface->Format() != gfxASurface::ImageFormatARGB32 &&
|
||||
|
@ -1251,9 +1290,7 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
|
|||
context->Translate(-gfxPoint(aSrcRect.x, aSrcRect.y));
|
||||
context->SetSource(aSurface);
|
||||
context->Paint();
|
||||
data = imageSurface->Data();
|
||||
} else {
|
||||
data = imageSurface->Data();
|
||||
data += aSrcRect.y * imageSurface->Stride();
|
||||
data += aSrcRect.x * 4;
|
||||
}
|
||||
|
|
|
@ -279,16 +279,8 @@ class BasicTextureImage
|
|||
: public TextureImage
|
||||
{
|
||||
public:
|
||||
virtual ~BasicTextureImage();
|
||||
|
||||
virtual gfxContext* BeginUpdate(nsIntRegion& aRegion);
|
||||
virtual PRBool EndUpdate();
|
||||
|
||||
virtual PRBool InUpdate() const { return !!mUpdateContext; }
|
||||
|
||||
virtual void Resize(const nsIntSize& aSize);
|
||||
protected:
|
||||
typedef gfxASurface::gfxImageFormat ImageFormat;
|
||||
virtual ~BasicTextureImage();
|
||||
|
||||
BasicTextureImage(GLuint aTexture,
|
||||
const nsIntSize& aSize,
|
||||
|
@ -301,8 +293,25 @@ protected:
|
|||
, mUpdateOffset(0, 0)
|
||||
{}
|
||||
|
||||
virtual gfxContext* BeginUpdate(nsIntRegion& aRegion);
|
||||
virtual PRBool EndUpdate();
|
||||
|
||||
// Returns a surface to draw into
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt) = 0;
|
||||
GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
|
||||
|
||||
// Call when drawing into the update surface is complete.
|
||||
// Returns true if textures should be upload with a relative
|
||||
// offset - See UploadSurfaceToTexture.
|
||||
virtual bool FinishedSurfaceUpdate();
|
||||
|
||||
// Call after surface data has been uploaded to a texture.
|
||||
virtual void FinishedSurfaceUpload();
|
||||
|
||||
virtual PRBool InUpdate() const { return !!mUpdateContext; }
|
||||
|
||||
virtual void Resize(const nsIntSize& aSize);
|
||||
protected:
|
||||
|
||||
PRBool mTextureInited;
|
||||
GLContext* mGLContext;
|
||||
|
@ -746,13 +755,17 @@ public:
|
|||
* \param aTexture Texture to use, or 0 to have one created for you.
|
||||
* \param aOverwrite Over an existing texture with a new one.
|
||||
* \param aDstPoint Offset into existing texture to upload contents.
|
||||
* \param aPixelBuffer Pass true to upload texture data with an
|
||||
* offset from the base data (generally for pixel buffer objects),
|
||||
* otherwise textures are upload with an absolute pointer to the data.
|
||||
* \return Shader program needed to render this texture.
|
||||
*/
|
||||
ShaderProgramType UploadSurfaceToTexture(gfxASurface *aSurface,
|
||||
const nsIntRect& aSrcRect,
|
||||
GLuint& aTexture,
|
||||
bool aOverwrite = false,
|
||||
const nsIntPoint& aDstPoint = nsIntPoint(0, 0));
|
||||
const nsIntPoint& aDstPoint = nsIntPoint(0, 0),
|
||||
bool aPixelBuffer = PR_FALSE);
|
||||
|
||||
/** Helper for DecomposeIntoNoRepeatTriangles
|
||||
*/
|
||||
|
@ -808,6 +821,7 @@ public:
|
|||
EXT_read_format_bgra,
|
||||
APPLE_client_storage,
|
||||
ARB_texture_non_power_of_two,
|
||||
ARB_pixel_buffer_object,
|
||||
Extensions_Max
|
||||
};
|
||||
|
||||
|
@ -912,7 +926,11 @@ protected:
|
|||
GLenum aWrapMode,
|
||||
TextureImage::ContentType aContentType,
|
||||
GLContext* aContext)
|
||||
{ return NULL; }
|
||||
{
|
||||
nsRefPtr<BasicTextureImage> teximage(
|
||||
new BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext));
|
||||
return teximage.forget();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsTArray<nsIntRect> mViewportStack;
|
||||
|
@ -1842,6 +1860,20 @@ public:
|
|||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void* fMapBuffer(GLenum target, GLenum access) {
|
||||
BEFORE_GL_CALL;
|
||||
void *ret = mSymbols.fMapBuffer(target, access);
|
||||
AFTER_GL_CALL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
realGLboolean fUnmapBuffer(GLenum target) {
|
||||
BEFORE_GL_CALL;
|
||||
realGLboolean ret = mSymbols.fUnmapBuffer(target);
|
||||
AFTER_GL_CALL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DEBUG
|
||||
GLuint GLAPIENTRY fCreateProgram() {
|
||||
|
|
|
@ -294,72 +294,62 @@ class TextureImageCGL : public BasicTextureImage
|
|||
GLenum,
|
||||
TextureImage::ContentType,
|
||||
GLContext*);
|
||||
public:
|
||||
~TextureImageCGL()
|
||||
{
|
||||
if (mPixelBuffer) {
|
||||
mGLContext->fDeleteBuffers(1, &mPixelBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual gfxContext*
|
||||
BeginUpdate(nsIntRegion& aRegion)
|
||||
already_AddRefed<gfxASurface>
|
||||
GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
|
||||
{
|
||||
ImageFormat format;
|
||||
if (GetContentType() == gfxASurface::CONTENT_COLOR)
|
||||
format = gfxASurface::ImageFormatRGB24;
|
||||
else
|
||||
format = gfxASurface::ImageFormatARGB32;
|
||||
|
||||
if (!mTextureInited || !mUpdateSurface ||
|
||||
mUpdateSurface->GetContentType() != GetContentType())
|
||||
{
|
||||
mUpdateSurface = nsnull;
|
||||
mUpdateOffset = nsIntPoint(0, 0);
|
||||
// We need to (re)create our backing store. Let the base class to that.
|
||||
return BasicTextureImage::BeginUpdate(aRegion);
|
||||
if (!mGLContext->IsExtensionSupported(GLContext::ARB_pixel_buffer_object)) {
|
||||
return gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imageSurface = mUpdateSurface->GetAsImageSurface();
|
||||
if (!imageSurface ||
|
||||
nsIntSize(imageSurface->Width(), imageSurface->Height()) < mSize) {
|
||||
mUpdateSurface = nsnull;
|
||||
mUpdateOffset = nsIntPoint(0, 0);
|
||||
// We need to (re)create our backing store. Let the base class to that.
|
||||
return BasicTextureImage::BeginUpdate(aRegion);
|
||||
if (!mPixelBuffer) {
|
||||
mGLContext->fGenBuffers(1, &mPixelBuffer);
|
||||
}
|
||||
mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
|
||||
PRInt32 size = aSize.width * 4 * aSize.height;
|
||||
|
||||
if (size > mPixelBufferSize) {
|
||||
mGLContext->fBufferData(LOCAL_GL_PIXEL_UNPACK_BUFFER, size,
|
||||
NULL, LOCAL_GL_STREAM_DRAW);
|
||||
mPixelBufferSize = size;
|
||||
}
|
||||
unsigned char* data =
|
||||
(unsigned char*)mGLContext->fMapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, LOCAL_GL_WRITE_ONLY);
|
||||
|
||||
if (!data) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// the basic impl can only upload updates to rectangles
|
||||
mUpdateRect = aRegion.GetBounds();
|
||||
aRegion = nsIntRegion(mUpdateRect);
|
||||
nsRefPtr<gfxQuartzSurface> surf =
|
||||
new gfxQuartzSurface(data, aSize,
|
||||
aSize.width * 4, aFmt);
|
||||
|
||||
if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) {
|
||||
NS_ERROR("update outside of image");
|
||||
return NULL;
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
bool FinishedSurfaceUpdate()
|
||||
{
|
||||
if (mPixelBuffer) {
|
||||
mGLContext->fUnmapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER);
|
||||
return true;
|
||||
}
|
||||
|
||||
mUpdateContext = new gfxContext(mUpdateSurface);
|
||||
mUpdateContext->Clip(gfxRect(mUpdateRect.x, mUpdateRect.y,
|
||||
mUpdateRect.width, mUpdateRect.height));
|
||||
if (GetContentType() != gfxASurface::CONTENT_COLOR)
|
||||
{
|
||||
mUpdateContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
mUpdateContext->Paint();
|
||||
mUpdateContext->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
}
|
||||
mUpdateOffset = mUpdateRect.TopLeft();
|
||||
|
||||
return mUpdateContext;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual PRBool
|
||||
EndUpdate()
|
||||
void FinishedSurfaceUpload()
|
||||
{
|
||||
if (!mUpdateSurface)
|
||||
mUpdateSurface = mUpdateContext->OriginalSurface();
|
||||
|
||||
return BasicTextureImage::EndUpdate();
|
||||
}
|
||||
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt)
|
||||
{
|
||||
mUpdateFormat = aFmt;
|
||||
return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
|
||||
if (mPixelBuffer) {
|
||||
mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -369,10 +359,12 @@ private:
|
|||
ContentType aContentType,
|
||||
GLContext* aContext)
|
||||
: BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext)
|
||||
, mPixelBuffer(0)
|
||||
, mPixelBufferSize(0)
|
||||
{}
|
||||
|
||||
ImageFormat mUpdateFormat;
|
||||
nsRefPtr<gfxASurface> mUpdateSurface;
|
||||
|
||||
GLuint mPixelBuffer;
|
||||
PRInt32 mPixelBufferSize;
|
||||
};
|
||||
|
||||
already_AddRefed<TextureImage>
|
||||
|
|
|
@ -370,13 +370,6 @@ TRY_AGAIN_NO_SHARING:
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
virtual already_AddRefed<TextureImage>
|
||||
CreateBasicTextureImage(GLuint aTexture,
|
||||
const nsIntSize& aSize,
|
||||
GLenum aWrapMode,
|
||||
TextureImage::ContentType aContentType,
|
||||
GLContext* aContext);
|
||||
|
||||
private:
|
||||
friend class GLContextProviderGLX;
|
||||
|
||||
|
@ -406,50 +399,6 @@ private:
|
|||
nsRefPtr<gfxXlibSurface> mPixmap;
|
||||
};
|
||||
|
||||
// FIXME/bug 575505: this is a (very slow!) placeholder
|
||||
// implementation. Much better would be to create a Pixmap, wrap that
|
||||
// in a GLXPixmap, and then glXBindTexImage() to our texture.
|
||||
class TextureImageGLX : public BasicTextureImage
|
||||
{
|
||||
friend already_AddRefed<TextureImage>
|
||||
GLContextGLX::CreateBasicTextureImage(GLuint,
|
||||
const nsIntSize&,
|
||||
GLenum,
|
||||
TextureImage::ContentType,
|
||||
GLContext*);
|
||||
|
||||
protected:
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt)
|
||||
{
|
||||
mUpdateFormat = aFmt;
|
||||
return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
|
||||
}
|
||||
|
||||
private:
|
||||
TextureImageGLX(GLuint aTexture,
|
||||
const nsIntSize& aSize,
|
||||
GLenum aWrapMode,
|
||||
ContentType aContentType,
|
||||
GLContext* aContext)
|
||||
: BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext)
|
||||
{}
|
||||
|
||||
ImageFormat mUpdateFormat;
|
||||
};
|
||||
|
||||
already_AddRefed<TextureImage>
|
||||
GLContextGLX::CreateBasicTextureImage(GLuint aTexture,
|
||||
const nsIntSize& aSize,
|
||||
GLenum aWrapMode,
|
||||
TextureImage::ContentType aContentType,
|
||||
GLContext* aContext)
|
||||
{
|
||||
nsRefPtr<TextureImageGLX> teximage(
|
||||
new TextureImageGLX(aTexture, aSize, aWrapMode, aContentType, aContext));
|
||||
return teximage.forget();
|
||||
}
|
||||
|
||||
static GLContextGLX *
|
||||
GetGlobalContextGLX()
|
||||
{
|
||||
|
|
|
@ -327,13 +327,6 @@ public:
|
|||
|
||||
HGLRC Context() { return mContext; }
|
||||
|
||||
virtual already_AddRefed<TextureImage>
|
||||
CreateBasicTextureImage(GLuint aTexture,
|
||||
const nsIntSize& aSize,
|
||||
GLenum aWrapMode,
|
||||
TextureImage::ContentType aContentType,
|
||||
GLContext* aContext);
|
||||
|
||||
protected:
|
||||
friend class GLContextProviderWGL;
|
||||
|
||||
|
@ -445,50 +438,6 @@ GetGlobalContextWGL()
|
|||
return static_cast<GLContextWGL*>(GLContextProviderWGL::GetGlobalContext());
|
||||
}
|
||||
|
||||
class TextureImageWGL : public BasicTextureImage
|
||||
{
|
||||
friend already_AddRefed<TextureImage>
|
||||
GLContextWGL::CreateBasicTextureImage(GLuint,
|
||||
const nsIntSize&,
|
||||
GLenum,
|
||||
TextureImage::ContentType,
|
||||
GLContext*);
|
||||
|
||||
protected:
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt)
|
||||
{
|
||||
mUpdateSize = aSize;
|
||||
mUpdateFormat = aFmt;
|
||||
|
||||
return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
|
||||
}
|
||||
|
||||
private:
|
||||
TextureImageWGL(GLuint aTexture,
|
||||
const nsIntSize& aSize,
|
||||
GLenum aWrapMode,
|
||||
ContentType aContentType,
|
||||
GLContext* aContext)
|
||||
: BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext)
|
||||
{}
|
||||
|
||||
gfxIntSize mUpdateSize;
|
||||
ImageFormat mUpdateFormat;
|
||||
};
|
||||
|
||||
already_AddRefed<TextureImage>
|
||||
GLContextWGL::CreateBasicTextureImage(GLuint aTexture,
|
||||
const nsIntSize& aSize,
|
||||
GLenum aWrapMode,
|
||||
TextureImage::ContentType aContentType,
|
||||
GLContext* aContext)
|
||||
{
|
||||
nsRefPtr<TextureImageWGL> teximage
|
||||
(new TextureImageWGL(aTexture, aSize, aWrapMode, aContentType, aContext));
|
||||
return teximage.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
|
||||
{
|
||||
|
|
|
@ -363,6 +363,11 @@ struct GLContextSymbols
|
|||
typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERS) (GLsizei n, const GLuint* ids);
|
||||
PFNGLDELETERENDERBUFFERS fDeleteRenderbuffers;
|
||||
|
||||
typedef void* (GLAPIENTRY * PFNGLMAPBUFFER) (GLenum target, GLenum access);
|
||||
PFNGLMAPBUFFER fMapBuffer;
|
||||
typedef realGLboolean (GLAPIENTRY * PFNGLUNMAPBUFFER) (GLenum target);
|
||||
PFNGLUNMAPBUFFER fUnmapBuffer;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -844,6 +844,7 @@ typedef ptrdiff_t GLintptr;
|
|||
#define LOCAL_GL_DYNAMIC_DRAW 0x88E8
|
||||
#define LOCAL_GL_DYNAMIC_READ 0x88E9
|
||||
#define LOCAL_GL_DYNAMIC_COPY 0x88EA
|
||||
#define LOCAL_GL_PIXEL_UNPACK_BUFFER 0x88EC
|
||||
#define LOCAL_GL_SAMPLES_PASSED 0x8914
|
||||
#define LOCAL_GL_VERSION_2_0 1
|
||||
#define LOCAL_GL_BLEND_EQUATION_RGB 0x8009
|
||||
|
|
Загрузка…
Ссылка в новой задаче