am 28333315: Merge "Added support for the GL_TEXTURE_EXTERNAL target" into gingerbread
Merge commit '28333315c6f62b303de2ec0ac9e48158ed419f06' into gingerbread-plus-aosp * commit '28333315c6f62b303de2ec0ac9e48158ed419f06': Added support for the GL_TEXTURE_EXTERNAL target
This commit is contained in:
@@ -232,7 +232,7 @@ void Layer::onDraw(const Region& clip) const
|
|||||||
// if not everything below us is covered, we plug the holes!
|
// if not everything below us is covered, we plug the holes!
|
||||||
Region holes(clip.subtract(under));
|
Region holes(clip.subtract(under));
|
||||||
if (!holes.isEmpty()) {
|
if (!holes.isEmpty()) {
|
||||||
clearWithOpenGL(holes);
|
clearWithOpenGL(holes, 0, 0, 0, 1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -324,16 +324,6 @@ void LayerBase::draw(const Region& inClip) const
|
|||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
onDraw(clip);
|
onDraw(clip);
|
||||||
|
|
||||||
/*
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glDisable(GL_DITHER);
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
glColor4x(0, 0x8000, 0, 0x10000);
|
|
||||||
drawRegion(transparentRegionScreen);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
|
void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
|
||||||
@@ -343,7 +333,9 @@ void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
|
|||||||
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
||||||
const uint32_t fbHeight = hw.getHeight();
|
const uint32_t fbHeight = hw.getHeight();
|
||||||
glColor4f(red,green,blue,alpha);
|
glColor4f(red,green,blue,alpha);
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
|
TextureManager::deactivateTextures();
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_DITHER);
|
glDisable(GL_DITHER);
|
||||||
|
|
||||||
@@ -371,11 +363,9 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
|
|||||||
const State& s(drawingState());
|
const State& s(drawingState());
|
||||||
|
|
||||||
// bind our texture
|
// bind our texture
|
||||||
validateTexture(texture.name);
|
TextureManager::activateTexture(texture, needsFiltering());
|
||||||
uint32_t width = texture.width;
|
uint32_t width = texture.width;
|
||||||
uint32_t height = texture.height;
|
uint32_t height = texture.height;
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
|
GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
|
||||||
if (UNLIKELY(s.alpha < 0xFF)) {
|
if (UNLIKELY(s.alpha < 0xFF)) {
|
||||||
@@ -431,6 +421,12 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
|
|||||||
glScalef(texture.wScale, texture.hScale, 1.0f);
|
glScalef(texture.wScale, texture.hScale, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsDithering()) {
|
||||||
|
glEnable(GL_DITHER);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_DITHER);
|
||||||
|
}
|
||||||
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glVertexPointer(2, GL_FLOAT, 0, mVertices);
|
glVertexPointer(2, GL_FLOAT, 0, mVertices);
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
||||||
@@ -444,26 +440,6 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
|
|||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerBase::validateTexture(GLint textureName) const
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textureName);
|
|
||||||
// TODO: reload the texture if needed
|
|
||||||
// this is currently done in loadTexture() below
|
|
||||||
if (needsFiltering()) {
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
} else {
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsDithering()) {
|
|
||||||
glEnable(GL_DITHER);
|
|
||||||
} else {
|
|
||||||
glDisable(GL_DITHER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
|
void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
|
||||||
{
|
{
|
||||||
const Layer::State& s(drawingState());
|
const Layer::State& s(drawingState());
|
||||||
|
|||||||
@@ -260,7 +260,6 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
LayerBase(const LayerBase& rhs);
|
LayerBase(const LayerBase& rhs);
|
||||||
void validateTexture(GLint textureName) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,9 @@ void LayerBlur::onDraw(const Region& clip) const
|
|||||||
Region::const_iterator it = clip.begin();
|
Region::const_iterator it = clip.begin();
|
||||||
Region::const_iterator const end = clip.end();
|
Region::const_iterator const end = clip.end();
|
||||||
if (it != end) {
|
if (it != end) {
|
||||||
|
#if defined(GL_OES_texture_external)
|
||||||
|
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
#endif
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, mTextureName);
|
glBindTexture(GL_TEXTURE_2D, mTextureName);
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,9 @@ void LayerDim::onDraw(const Region& clip) const
|
|||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glColor4x(0, 0, 0, alpha);
|
glColor4x(0, 0, 0, alpha);
|
||||||
|
|
||||||
|
#if defined(GL_OES_texture_external)
|
||||||
|
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
#endif
|
||||||
#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)
|
#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)
|
||||||
if (sUseTexture) {
|
if (sUseTexture) {
|
||||||
glBindTexture(GL_TEXTURE_2D, sTexId);
|
glBindTexture(GL_TEXTURE_2D, sTexId);
|
||||||
|
|||||||
@@ -332,13 +332,6 @@ status_t SurfaceFlinger::readyToRun()
|
|||||||
dcblk->density = hw.getDensity();
|
dcblk->density = hw.getDensity();
|
||||||
|
|
||||||
// Initialize OpenGL|ES
|
// Initialize OpenGL|ES
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
@@ -918,17 +911,18 @@ void SurfaceFlinger::unlockClients()
|
|||||||
|
|
||||||
void SurfaceFlinger::debugFlashRegions()
|
void SurfaceFlinger::debugFlashRegions()
|
||||||
{
|
{
|
||||||
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
||||||
const uint32_t flags = hw.getFlags();
|
const uint32_t flags = hw.getFlags();
|
||||||
|
|
||||||
|
if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
|
||||||
|
(flags & DisplayHardware::BUFFER_PRESERVED))) {
|
||||||
|
const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
|
||||||
|
mDirtyRegion.bounds() : hw.bounds());
|
||||||
|
composeSurfaces(repaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureManager::deactivateTextures();
|
||||||
|
|
||||||
if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
|
|
||||||
(flags & DisplayHardware::BUFFER_PRESERVED))) {
|
|
||||||
const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
|
|
||||||
mDirtyRegion.bounds() : hw.bounds());
|
|
||||||
composeSurfaces(repaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_DITHER);
|
glDisable(GL_DITHER);
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
@@ -936,9 +930,9 @@ void SurfaceFlinger::debugFlashRegions()
|
|||||||
static int toggle = 0;
|
static int toggle = 0;
|
||||||
toggle = 1 - toggle;
|
toggle = 1 - toggle;
|
||||||
if (toggle) {
|
if (toggle) {
|
||||||
glColor4x(0x10000, 0, 0x10000, 0x10000);
|
glColor4f(1, 0, 1, 1);
|
||||||
} else {
|
} else {
|
||||||
glColor4x(0x10000, 0x10000, 0, 0x10000);
|
glColor4f(1, 1, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Region::const_iterator it = mDirtyRegion.begin();
|
Region::const_iterator it = mDirtyRegion.begin();
|
||||||
@@ -954,7 +948,7 @@ void SurfaceFlinger::debugFlashRegions()
|
|||||||
glVertexPointer(2, GL_FLOAT, 0, vertices);
|
glVertexPointer(2, GL_FLOAT, 0, vertices);
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mInvalidRegion.isEmpty()) {
|
if (mInvalidRegion.isEmpty()) {
|
||||||
mDirtyRegion.dump("mDirtyRegion");
|
mDirtyRegion.dump("mDirtyRegion");
|
||||||
mInvalidRegion.dump("mInvalidRegion");
|
mInvalidRegion.dump("mInvalidRegion");
|
||||||
@@ -962,7 +956,7 @@ void SurfaceFlinger::debugFlashRegions()
|
|||||||
hw.flip(mInvalidRegion);
|
hw.flip(mInvalidRegion);
|
||||||
|
|
||||||
if (mDebugRegion > 1)
|
if (mDebugRegion > 1)
|
||||||
usleep(mDebugRegion * 1000);
|
usleep(mDebugRegion * 1000);
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
//mDirtyRegion.dump("mDirtyRegion");
|
//mDirtyRegion.dump("mDirtyRegion");
|
||||||
@@ -982,7 +976,7 @@ void SurfaceFlinger::drawWormhole() const
|
|||||||
glDisable(GL_DITHER);
|
glDisable(GL_DITHER);
|
||||||
|
|
||||||
if (LIKELY(!mDebugBackground)) {
|
if (LIKELY(!mDebugBackground)) {
|
||||||
glClearColorx(0,0,0,0);
|
glClearColor(0,0,0,0);
|
||||||
Region::const_iterator it = region.begin();
|
Region::const_iterator it = region.begin();
|
||||||
Region::const_iterator const end = region.end();
|
Region::const_iterator const end = region.end();
|
||||||
while (it != end) {
|
while (it != end) {
|
||||||
@@ -998,6 +992,9 @@ void SurfaceFlinger::drawWormhole() const
|
|||||||
glVertexPointer(2, GL_SHORT, 0, vertices);
|
glVertexPointer(2, GL_SHORT, 0, vertices);
|
||||||
glTexCoordPointer(2, GL_SHORT, 0, tcoords);
|
glTexCoordPointer(2, GL_SHORT, 0, tcoords);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
#if defined(GL_OES_texture_external)
|
||||||
|
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
#endif
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
|
glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
|
||||||
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
|||||||
@@ -41,43 +41,112 @@ TextureManager::TextureManager(uint32_t flags)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint TextureManager::createTexture()
|
GLenum TextureManager::getTextureTarget(const Image* image) {
|
||||||
|
#if defined(GL_OES_texture_external)
|
||||||
|
switch (image->target) {
|
||||||
|
case Texture::TEXTURE_EXTERNAL:
|
||||||
|
return GL_TEXTURE_EXTERNAL_OES;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return GL_TEXTURE_2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t TextureManager::initTexture(Texture* texture)
|
||||||
{
|
{
|
||||||
|
if (texture->name != -1UL)
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
|
||||||
GLuint textureName = -1;
|
GLuint textureName = -1;
|
||||||
glGenTextures(1, &textureName);
|
glGenTextures(1, &textureName);
|
||||||
glBindTexture(GL_TEXTURE_2D, textureName);
|
texture->name = textureName;
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
texture->width = 0;
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
texture->height = 0;
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
const GLenum target = GL_TEXTURE_2D;
|
||||||
return textureName;
|
glBindTexture(target, textureName);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t TextureManager::initTexture(Image* pImage, int32_t format)
|
||||||
|
{
|
||||||
|
if (pImage->name != -1UL)
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
|
||||||
|
GLuint textureName = -1;
|
||||||
|
glGenTextures(1, &textureName);
|
||||||
|
pImage->name = textureName;
|
||||||
|
pImage->width = 0;
|
||||||
|
pImage->height = 0;
|
||||||
|
|
||||||
|
GLenum target = GL_TEXTURE_2D;
|
||||||
|
#if defined(GL_OES_texture_external)
|
||||||
|
if (format && isSupportedYuvFormat(format)) {
|
||||||
|
target = GL_TEXTURE_EXTERNAL_OES;
|
||||||
|
pImage->target = Texture::TEXTURE_EXTERNAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glBindTexture(target, textureName);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureManager::isSupportedYuvFormat(int format)
|
bool TextureManager::isSupportedYuvFormat(int format)
|
||||||
|
{
|
||||||
|
// TODO: how to we know which YUV formats are supported by the GPU?
|
||||||
|
|
||||||
|
// Adreno 200 supports these
|
||||||
|
// YUVY_adreno
|
||||||
|
// UYVY_adreno
|
||||||
|
// NV21_adreno
|
||||||
|
// YV12_adreno
|
||||||
|
// Adreno 205 adds
|
||||||
|
// NV12_adreno_tiled
|
||||||
|
// NV21_adreno_tiled
|
||||||
|
|
||||||
|
// for now pretend we support them all, failure will happen when
|
||||||
|
// we try to use them.
|
||||||
|
return isYuvFormat(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureManager::isYuvFormat(int format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
|
case HAL_PIXEL_FORMAT_NV16:
|
||||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
|
case HAL_PIXEL_FORMAT_NV21:
|
||||||
case HAL_PIXEL_FORMAT_YCbCr_422_P:
|
case HAL_PIXEL_FORMAT_IYUV:
|
||||||
case HAL_PIXEL_FORMAT_YCbCr_420_P:
|
case HAL_PIXEL_FORMAT_YUV9:
|
||||||
case HAL_PIXEL_FORMAT_YCbCr_422_I:
|
case HAL_PIXEL_FORMAT_YUY2:
|
||||||
case HAL_PIXEL_FORMAT_YCbCr_420_I:
|
case HAL_PIXEL_FORMAT_UYVY:
|
||||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
case HAL_PIXEL_FORMAT_NV12:
|
||||||
return true;
|
case HAL_PIXEL_FORMAT_NV61:
|
||||||
|
case HAL_PIXEL_FORMAT_YV12:
|
||||||
|
case HAL_PIXEL_FORMAT_NV12_ADRENO_TILED:
|
||||||
|
case HAL_PIXEL_FORMAT_NV21_ADRENO_TILED:
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t TextureManager::initEglImage(Image* texture,
|
status_t TextureManager::initEglImage(Image* pImage,
|
||||||
EGLDisplay dpy, const sp<GraphicBuffer>& buffer)
|
EGLDisplay dpy, const sp<GraphicBuffer>& buffer)
|
||||||
{
|
{
|
||||||
status_t err = NO_ERROR;
|
status_t err = NO_ERROR;
|
||||||
if (!texture->dirty) return err;
|
if (!pImage->dirty) return err;
|
||||||
|
|
||||||
// free the previous image
|
// free the previous image
|
||||||
if (texture->image != EGL_NO_IMAGE_KHR) {
|
if (pImage->image != EGL_NO_IMAGE_KHR) {
|
||||||
eglDestroyImageKHR(dpy, texture->image);
|
eglDestroyImageKHR(dpy, pImage->image);
|
||||||
texture->image = EGL_NO_IMAGE_KHR;
|
pImage->image = EGL_NO_IMAGE_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct an EGL_NATIVE_BUFFER_ANDROID
|
// construct an EGL_NATIVE_BUFFER_ANDROID
|
||||||
@@ -88,29 +157,27 @@ status_t TextureManager::initEglImage(Image* texture,
|
|||||||
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
|
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
|
||||||
EGL_NONE, EGL_NONE
|
EGL_NONE, EGL_NONE
|
||||||
};
|
};
|
||||||
texture->image = eglCreateImageKHR(
|
pImage->image = eglCreateImageKHR(
|
||||||
dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
|
dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
|
||||||
(EGLClientBuffer)clientBuf, attrs);
|
(EGLClientBuffer)clientBuf, attrs);
|
||||||
|
|
||||||
if (texture->image != EGL_NO_IMAGE_KHR) {
|
if (pImage->image != EGL_NO_IMAGE_KHR) {
|
||||||
if (texture->name == -1UL) {
|
if (pImage->name == -1UL) {
|
||||||
texture->name = createTexture();
|
initTexture(pImage, buffer->format);
|
||||||
texture->width = 0;
|
|
||||||
texture->height = 0;
|
|
||||||
}
|
}
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->name);
|
const GLenum target = getTextureTarget(pImage);
|
||||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
|
glBindTexture(target, pImage->name);
|
||||||
(GLeglImageOES)texture->image);
|
glEGLImageTargetTexture2DOES(target, (GLeglImageOES)pImage->image);
|
||||||
GLint error = glGetError();
|
GLint error = glGetError();
|
||||||
if (error != GL_NO_ERROR) {
|
if (error != GL_NO_ERROR) {
|
||||||
LOGE("glEGLImageTargetTexture2DOES(%p) failed err=0x%04x",
|
LOGE("glEGLImageTargetTexture2DOES(%p) failed err=0x%04x",
|
||||||
texture->image, error);
|
pImage->image, error);
|
||||||
err = INVALID_OPERATION;
|
err = INVALID_OPERATION;
|
||||||
} else {
|
} else {
|
||||||
// Everything went okay!
|
// Everything went okay!
|
||||||
texture->dirty = false;
|
pImage->dirty = false;
|
||||||
texture->width = clientBuf->width;
|
pImage->width = clientBuf->width;
|
||||||
texture->height = clientBuf->height;
|
pImage->height = clientBuf->height;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError());
|
LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError());
|
||||||
@@ -123,11 +190,14 @@ status_t TextureManager::loadTexture(Texture* texture,
|
|||||||
const Region& dirty, const GGLSurface& t)
|
const Region& dirty, const GGLSurface& t)
|
||||||
{
|
{
|
||||||
if (texture->name == -1UL) {
|
if (texture->name == -1UL) {
|
||||||
texture->name = createTexture();
|
status_t err = initTexture(texture);
|
||||||
texture->width = 0;
|
LOGE_IF(err, "loadTexture failed in initTexture (%s)", strerror(err));
|
||||||
texture->height = 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (texture->target != GL_TEXTURE_2D)
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->name);
|
glBindTexture(GL_TEXTURE_2D, texture->name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -197,7 +267,7 @@ status_t TextureManager::loadTexture(Texture* texture,
|
|||||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||||
GL_RGBA, texture->potWidth, texture->potHeight, 0,
|
GL_RGBA, texture->potWidth, texture->potHeight, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
} else if (isSupportedYuvFormat(t.format)) {
|
} else if (isYuvFormat(t.format)) {
|
||||||
// just show the Y plane of YUV buffers
|
// just show the Y plane of YUV buffers
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||||
GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
|
GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
|
||||||
@@ -225,7 +295,7 @@ status_t TextureManager::loadTexture(Texture* texture,
|
|||||||
0, bounds.top, t.width, bounds.height(),
|
0, bounds.top, t.width, bounds.height(),
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
t.data + bounds.top*t.stride*4);
|
t.data + bounds.top*t.stride*4);
|
||||||
} else if (isSupportedYuvFormat(t.format)) {
|
} else if (isYuvFormat(t.format)) {
|
||||||
// just show the Y plane of YUV buffers
|
// just show the Y plane of YUV buffers
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||||
0, bounds.top, t.width, bounds.height(),
|
0, bounds.top, t.width, bounds.height(),
|
||||||
@@ -236,6 +306,38 @@ status_t TextureManager::loadTexture(Texture* texture,
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureManager::activateTexture(const Texture& texture, bool filter)
|
||||||
|
{
|
||||||
|
const GLenum target = getTextureTarget(&texture);
|
||||||
|
|
||||||
|
glBindTexture(target, texture.name);
|
||||||
|
glEnable(target);
|
||||||
|
|
||||||
|
#if defined(GL_OES_texture_external)
|
||||||
|
if (texture.target == Texture::TEXTURE_2D) {
|
||||||
|
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
} else {
|
||||||
|
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureManager::deactivateTextures()
|
||||||
|
{
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
#if defined(GL_OES_texture_external)
|
||||||
|
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|||||||
@@ -37,31 +37,36 @@ class GraphicBuffer;
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
struct Image {
|
struct Image {
|
||||||
|
enum { TEXTURE_2D=0, TEXTURE_EXTERNAL=1 };
|
||||||
Image() : name(-1U), image(EGL_NO_IMAGE_KHR), width(0), height(0),
|
Image() : name(-1U), image(EGL_NO_IMAGE_KHR), width(0), height(0),
|
||||||
transform(0), dirty(true) { }
|
transform(0), dirty(1), target(TEXTURE_2D) { }
|
||||||
GLuint name;
|
GLuint name;
|
||||||
EGLImageKHR image;
|
EGLImageKHR image;
|
||||||
GLuint width;
|
GLuint width;
|
||||||
GLuint height;
|
GLuint height;
|
||||||
uint32_t transform;
|
uint32_t transform;
|
||||||
bool dirty;
|
unsigned dirty : 1;
|
||||||
|
unsigned target : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Texture : public Image {
|
struct Texture : public Image {
|
||||||
Texture() : Image(), NPOTAdjust(false) { }
|
Texture() : Image(), NPOTAdjust(0) { }
|
||||||
GLuint potWidth;
|
GLuint potWidth;
|
||||||
GLuint potHeight;
|
GLuint potHeight;
|
||||||
GLfloat wScale;
|
GLfloat wScale;
|
||||||
GLfloat hScale;
|
GLfloat hScale;
|
||||||
bool NPOTAdjust;
|
unsigned NPOTAdjust : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class TextureManager {
|
class TextureManager {
|
||||||
uint32_t mFlags;
|
uint32_t mFlags;
|
||||||
GLuint createTexture();
|
static status_t initTexture(Image* texture, int32_t format);
|
||||||
|
static status_t initTexture(Texture* texture);
|
||||||
static bool isSupportedYuvFormat(int format);
|
static bool isSupportedYuvFormat(int format);
|
||||||
|
static bool isYuvFormat(int format);
|
||||||
|
static GLenum getTextureTarget(const Image* pImage);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TextureManager(uint32_t flags);
|
TextureManager(uint32_t flags);
|
||||||
@@ -73,6 +78,12 @@ public:
|
|||||||
// make active buffer an EGLImage if needed
|
// make active buffer an EGLImage if needed
|
||||||
status_t initEglImage(Image* texture,
|
status_t initEglImage(Image* texture,
|
||||||
EGLDisplay dpy, const sp<GraphicBuffer>& buffer);
|
EGLDisplay dpy, const sp<GraphicBuffer>& buffer);
|
||||||
|
|
||||||
|
// activate a texture
|
||||||
|
static void activateTexture(const Texture& texture, bool filter);
|
||||||
|
|
||||||
|
// deactivate a texture
|
||||||
|
static void deactivateTextures();
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -70,8 +70,6 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
|
|||||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
|
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
|
||||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP_TILED:
|
case HAL_PIXEL_FORMAT_YCrCb_420_SP_TILED:
|
||||||
case HAL_PIXEL_FORMAT_YCbCr_420_P:
|
case HAL_PIXEL_FORMAT_YCbCr_420_P:
|
||||||
case HAL_PIXEL_FORMAT_YCbCr_420_I:
|
|
||||||
case HAL_PIXEL_FORMAT_CbYCrY_420_I:
|
|
||||||
info->bitsPerPixel = 12;
|
info->bitsPerPixel = 12;
|
||||||
done:
|
done:
|
||||||
info->format = format;
|
info->format = format;
|
||||||
|
|||||||
@@ -211,6 +211,11 @@ typedef void* GLeglImageOES;
|
|||||||
#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
|
#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* GL_OES_texture_external */
|
||||||
|
#ifndef GL_TEXTURE_EXTERNAL_OES
|
||||||
|
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
|
||||||
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*
|
/*------------------------------------------------------------------------*
|
||||||
* AMD extension tokens
|
* AMD extension tokens
|
||||||
*------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------*/
|
||||||
@@ -777,6 +782,11 @@ typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arra
|
|||||||
typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
|
typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* GL_OES_texture_external */
|
||||||
|
#ifndef GL_OES_texture_external
|
||||||
|
#define GL_OES_texture_external 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*
|
/*------------------------------------------------------------------------*
|
||||||
* AMD extension functions
|
* AMD extension functions
|
||||||
*------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------*/
|
||||||
|
|||||||
@@ -146,6 +146,11 @@ typedef void* GLeglImageOES;
|
|||||||
#define GL_INT_10_10_10_2_OES 0x8DF7
|
#define GL_INT_10_10_10_2_OES 0x8DF7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* GL_OES_texture_external */
|
||||||
|
#ifndef GL_TEXTURE_EXTERNAL_OES
|
||||||
|
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
|
||||||
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*
|
/*------------------------------------------------------------------------*
|
||||||
* AMD extension tokens
|
* AMD extension tokens
|
||||||
*------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------*/
|
||||||
@@ -541,6 +546,11 @@ typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
|
|||||||
#define GL_OES_vertex_type_10_10_10_2 1
|
#define GL_OES_vertex_type_10_10_10_2 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* GL_OES_texture_external */
|
||||||
|
#ifndef GL_OES_texture_external
|
||||||
|
#define GL_OES_texture_external 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*
|
/*------------------------------------------------------------------------*
|
||||||
* AMD extension functions
|
* AMD extension functions
|
||||||
*------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------*/
|
||||||
|
|||||||
Reference in New Issue
Block a user