Merge branch 'DRTVWR-546' of https://bitbucket.org/lindenlab/viewer
commit
e7bc3f3a5a
|
|
@ -879,6 +879,12 @@ U8* LLImageRaw::reallocateData(S32 size)
|
|||
return res;
|
||||
}
|
||||
|
||||
void LLImageRaw::releaseData()
|
||||
{
|
||||
LLImageBase::setSize(0, 0, 0);
|
||||
LLImageBase::setDataAndSize(nullptr, 0);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLImageRaw::deleteData()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -198,6 +198,12 @@ public:
|
|||
/*virtual*/ void deleteData();
|
||||
/*virtual*/ U8* allocateData(S32 size = -1);
|
||||
/*virtual*/ U8* reallocateData(S32 size);
|
||||
|
||||
// use in conjunction with "no_copy" constructor to release data pointer before deleting
|
||||
// so that deletion of this LLImageRaw will not free the memory at the "data" parameter
|
||||
// provided to "no_copy" constructor
|
||||
void releaseData();
|
||||
|
||||
|
||||
bool resize(U16 width, U16 height, S8 components);
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ const F32 SKEW_MAX = 0.95f;
|
|||
const F32 SCULPT_MIN_AREA = 0.002f;
|
||||
const S32 SCULPT_MIN_AREA_DETAIL = 1;
|
||||
|
||||
BOOL gDebugGL = FALSE;
|
||||
BOOL gDebugGL = FALSE; // See settings.xml "RenderDebugGL"
|
||||
|
||||
// <FS:ND> Cache for Triangles/LOD estimation
|
||||
struct TrianglesPerLODCache
|
||||
|
|
|
|||
|
|
@ -760,17 +760,6 @@ bool LLGLManager::initGL()
|
|||
|
||||
stop_glerror();
|
||||
|
||||
#if LL_WINDOWS
|
||||
if (mHasDebugOutput && gDebugGL)
|
||||
{ //setup debug output callback
|
||||
//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
|
||||
glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
}
|
||||
#endif
|
||||
|
||||
stop_glerror();
|
||||
|
||||
//HACK always disable texture multisample, use FXAA instead
|
||||
mHasTextureMultisample = FALSE;
|
||||
#if LL_WINDOWS
|
||||
|
|
@ -1034,7 +1023,9 @@ void LLGLManager::initExtensions()
|
|||
mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
|
||||
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
|
||||
mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
|
||||
mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
|
||||
// NOTE: Using extensions breaks reflections when Shadows are set to projector. See: SL-16727
|
||||
//mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
|
||||
mHasDepthClamp = FALSE;
|
||||
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
|
||||
#ifdef GL_ARB_framebuffer_object
|
||||
mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
|
||||
|
|
|
|||
|
|
@ -164,11 +164,11 @@ BOOL LLGLTexture::createGLTexture()
|
|||
return mGLTexturep->createGLTexture() ;
|
||||
}
|
||||
|
||||
BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
|
||||
BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category, bool defer_copy)
|
||||
{
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
|
||||
BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category, defer_copy) ;
|
||||
|
||||
if(ret)
|
||||
{
|
||||
|
|
@ -260,20 +260,20 @@ LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
|
|||
return mGLTexturep->getTarget() ;
|
||||
}
|
||||
|
||||
BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
|
||||
BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool use_new_name /* = false */)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
|
||||
return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height, 0, use_new_name) ;
|
||||
}
|
||||
|
||||
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
|
||||
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool use_new_name /* = false */)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
llassert(mGLTexturep.notNull()) ;
|
||||
|
||||
return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
|
||||
return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height, 0, use_new_name) ;
|
||||
}
|
||||
|
||||
void LLGLTexture::setGLTextureCreated (bool initialized)
|
||||
|
|
|
|||
|
|
@ -124,13 +124,21 @@ public:
|
|||
BOOL hasGLTexture() const ;
|
||||
LLGLuint getTexName() const ;
|
||||
BOOL createGLTexture() ;
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER);
|
||||
|
||||
// Create a GL Texture from an image raw
|
||||
// discard_level - mip level, 0 for highest resultion mip
|
||||
// imageraw - the image to copy from
|
||||
// usename - explicit GL name override
|
||||
// to_create - set to FALSE to force gl texture to not be created
|
||||
// category - LLGLTexture category for this LLGLTexture
|
||||
// defer_copy - set to true to allocate GL texture but NOT initialize with imageraw data
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER, bool defer_copy = false);
|
||||
|
||||
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
|
||||
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
|
||||
void setAddressMode(LLTexUnit::eTextureAddressMode mode);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, bool use_new_name = false);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool use_new_name = false);
|
||||
void setGLTextureCreated (bool initialized);
|
||||
void setCategory(S32 category) ;
|
||||
void setTexName(LLGLuint); // for forcing w/ externally created textures only
|
||||
|
|
|
|||
|
|
@ -558,7 +558,7 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
|
|||
if (width != mWidth || height != mHeight || ncomponents != mComponents)
|
||||
{
|
||||
// Check if dimensions are a power of two!
|
||||
if (!checkSize(width,height))
|
||||
if (!checkSize(width, height))
|
||||
{
|
||||
LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL;
|
||||
return false;
|
||||
|
|
@ -682,7 +682,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
|
|||
setImage(rawdata, FALSE);
|
||||
}
|
||||
|
||||
BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips, S32 usename)
|
||||
BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32 usename /* = 0 */)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
bool is_compressed = false;
|
||||
|
|
@ -717,8 +717,14 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips, S32 usename)
|
|||
|
||||
gGL.getTexUnit(0)->bind(this, false, false, usename);
|
||||
|
||||
|
||||
if (mUseMipMaps)
|
||||
if (data_in == nullptr)
|
||||
{
|
||||
S32 w = getWidth();
|
||||
S32 h = getHeight();
|
||||
LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
|
||||
mFormatPrimary, mFormatType, (GLvoid*)data_in, mAllowCompression);
|
||||
}
|
||||
else if (mUseMipMaps)
|
||||
{
|
||||
if (data_hasmips)
|
||||
{
|
||||
|
|
@ -1077,14 +1083,14 @@ void LLImageGL::postAddToAtlas()
|
|||
stop_glerror();
|
||||
}
|
||||
|
||||
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
|
||||
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, bool use_new_name /* = false */)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
if (!width || !height)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (mTexName == 0)
|
||||
if (0 == (use_new_name ? mNewTexName : mTexName))
|
||||
{
|
||||
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
|
||||
//LL_WARNS() << "Setting subimage on image without GL texture" << LL_ENDL;
|
||||
|
|
@ -1100,7 +1106,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
// HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture.
|
||||
if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
|
||||
{
|
||||
setImage(datap, FALSE);
|
||||
setImage(datap, FALSE, use_new_name ? mNewTexName : mTexName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1152,12 +1158,11 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
|
||||
datap += (y_pos * data_width + x_pos) * getComponents();
|
||||
// Update the GL texture
|
||||
BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName);
|
||||
BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, use_new_name ? mNewTexName : mTexName);
|
||||
if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
|
||||
stop_glerror();
|
||||
|
||||
glTexSubImage2D(mTarget, 0, x_pos, y_pos,
|
||||
width, height, mFormatPrimary, mFormatType, datap);
|
||||
glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, datap);
|
||||
gGL.getTexUnit(0)->disable();
|
||||
stop_glerror();
|
||||
|
||||
|
|
@ -1174,10 +1179,10 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
|
||||
BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, bool use_new_name /* = false */)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update);
|
||||
return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update, use_new_name);
|
||||
}
|
||||
|
||||
// Copy sub image from frame buffer
|
||||
|
|
@ -1364,7 +1369,7 @@ BOOL LLImageGL::createGLTexture()
|
|||
return TRUE ;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category, bool defer_copy)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
checkActiveThread();
|
||||
|
|
@ -1394,6 +1399,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
// Actual image width/height = raw image width/height * 2^discard_level
|
||||
S32 raw_w = imageraw->getWidth() ;
|
||||
S32 raw_h = imageraw->getHeight() ;
|
||||
|
||||
S32 w = raw_w << discard_level;
|
||||
S32 h = raw_h << discard_level;
|
||||
|
||||
|
|
@ -1476,15 +1482,24 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
|
||||
setCategory(category);
|
||||
const U8* rawdata = imageraw->getData();
|
||||
return createGLTexture(discard_level, rawdata, FALSE, usename);
|
||||
return createGLTexture(discard_level, rawdata, FALSE, usename, defer_copy);
|
||||
}
|
||||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename, bool defer_copy)
|
||||
// Call with void data, vmem is allocated but unitialized
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
checkActiveThread();
|
||||
|
||||
llassert(data_in);
|
||||
if (defer_copy)
|
||||
{
|
||||
data_in = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(data_in);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (discard_level < 0)
|
||||
|
|
@ -1494,7 +1509,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
}
|
||||
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
|
||||
|
||||
if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
|
||||
if (!defer_copy // <--- hacky way to force creation of mNewTexName from media texture update
|
||||
&& mTexName != 0 && discard_level == mCurrentDiscardLevel)
|
||||
{
|
||||
// This will only be true if the size has not changed
|
||||
return setImage(data_in, data_hasmips);
|
||||
|
|
@ -1542,36 +1558,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
}
|
||||
|
||||
//if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread
|
||||
if (! on_main_thread())
|
||||
if (!on_main_thread())
|
||||
{
|
||||
if (!defer_copy)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - sync");
|
||||
if (gGLManager.mHasSync)
|
||||
{
|
||||
auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glClientWaitSync(sync, 0, 0);
|
||||
glDeleteSync(sync);
|
||||
}
|
||||
else
|
||||
{
|
||||
glFinish();
|
||||
}
|
||||
syncToMainThread();
|
||||
}
|
||||
|
||||
ref();
|
||||
LL::WorkQueue::postMaybe(
|
||||
mMainQueue,
|
||||
[=]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - delete callback");
|
||||
if (old_texname != 0)
|
||||
{
|
||||
LLImageGL::deleteTextures(1, &old_texname);
|
||||
}
|
||||
mTexName = mNewTexName;
|
||||
mNewTexName = 0;
|
||||
unref();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1595,6 +1587,55 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void LLImageGL::syncToMainThread()
|
||||
{
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - sync");
|
||||
if (gGLManager.mHasSync)
|
||||
{
|
||||
// post a sync to the main thread (will execute before tex name swap lambda below)
|
||||
auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
LL::WorkQueue::postMaybe(
|
||||
mMainQueue,
|
||||
[=]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - wait sync");
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("glWaitSync");
|
||||
glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("glDeleteSync");
|
||||
glDeleteSync(sync);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
glFinish();
|
||||
}
|
||||
}
|
||||
|
||||
ref();
|
||||
LL::WorkQueue::postMaybe(
|
||||
mMainQueue,
|
||||
[=]()
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cglt - delete callback");
|
||||
if (mNewTexName != 0)
|
||||
{
|
||||
if (mTexName != 0)
|
||||
{
|
||||
LLImageGL::deleteTextures(1, &mTexName);
|
||||
}
|
||||
mTexName = mNewTexName;
|
||||
mNewTexName = 0;
|
||||
unref();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
|
||||
{
|
||||
llassert_always(sAllowReadBackRaw) ;
|
||||
|
|
@ -1722,7 +1763,15 @@ void LLImageGL::destroyGLTexture()
|
|||
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
|
||||
mTexName = 0;
|
||||
mGLTextureCreated = FALSE ;
|
||||
}
|
||||
}
|
||||
|
||||
// clean up any in-flight name change
|
||||
if (0 != mNewTexName)
|
||||
{
|
||||
// Memory is transient, not tracked by sGlobalTextuerMemory
|
||||
LLImageGL::deleteTextures(1, &mNewTexName);
|
||||
mNewTexName = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//force to invalidate the gl texture, most likely a sculpty texture
|
||||
|
|
|
|||
|
|
@ -113,14 +113,18 @@ public:
|
|||
|
||||
BOOL createGLTexture() ;
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
|
||||
S32 category = sMaxCategories-1);
|
||||
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
|
||||
S32 category = sMaxCategories-1, bool defer_copy = false);
|
||||
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false);
|
||||
void setImage(const LLImageRaw* imageraw);
|
||||
BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, bool use_new_name = false);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, bool use_new_name = false);
|
||||
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
|
||||
|
||||
// wait for gl commands to finish on current thread and push
|
||||
// a lambda to main thread to swap mNewTexName and mTexName
|
||||
void syncToMainThread();
|
||||
|
||||
// Read back a raw image for this discard level, if it exists
|
||||
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
|
||||
void destroyGLTexture();
|
||||
|
|
|
|||
|
|
@ -36,6 +36,17 @@
|
|||
#include "lltexture.h"
|
||||
#include "llshadermgr.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
extern void APIENTRY gl_debug_callback(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
GLvoid* userParam)
|
||||
;
|
||||
#endif
|
||||
|
||||
thread_local LLRender gGL;
|
||||
|
||||
// Handy copies of last good GL matrices
|
||||
|
|
@ -868,6 +879,15 @@ LLRender::~LLRender()
|
|||
|
||||
void LLRender::init()
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
if (gGLManager.mHasDebugOutput && gDebugGL)
|
||||
{ //setup debug output callback
|
||||
//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
|
||||
glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
}
|
||||
#endif
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "llfilepicker.h"
|
||||
#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
|
||||
#include "llfocusmgr.h"
|
||||
#include "llimagegl.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "lllogininstance.h"
|
||||
#include "llmarketplacefunctions.h"
|
||||
|
|
@ -635,6 +636,7 @@ static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMedi
|
|||
static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE("Update Media");
|
||||
static LLTrace::BlockTimerStatHandle FTM_MEDIA_SPARE_IDLE("Spare Idle");
|
||||
static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE_INTEREST("Update/Interest");
|
||||
static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE_VOLUME("Update/Volume");
|
||||
static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT("Media Sort");
|
||||
static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT2("Media Sort 2");
|
||||
static LLTrace::BlockTimerStatHandle FTM_MEDIA_MISC("Misc");
|
||||
|
|
@ -658,6 +660,13 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
|
|||
LLPluginProcessParent::setUseReadThread(sPluginUseReadThread);
|
||||
// </FS:Ansariel>
|
||||
|
||||
// SL-16418 We can't call LLViewerMediaImpl->update() if we are in the state of shutting down.
|
||||
if(LLApp::isExiting())
|
||||
{
|
||||
setAllMediaEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
|
||||
// 2017-04-19 Removed CP - this doesn't appear to buy us much and consumes a lot of resources so
|
||||
// removing it for now.
|
||||
|
|
@ -1614,6 +1623,8 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
|
|||
media_tex->setMediaImpl();
|
||||
}
|
||||
|
||||
mMainQueue = LL::WorkQueue::getInstance("mainloop");
|
||||
mTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1700,11 +1711,13 @@ void LLViewerMediaImpl::destroyMediaSource()
|
|||
|
||||
cancelMimeTypeProbe();
|
||||
|
||||
mLock.lock(); // Delay tear-down while bg thread is updating
|
||||
if(mMediaSource)
|
||||
{
|
||||
mMediaSource->setDeleteOK(true) ;
|
||||
mMediaSource = NULL; // shared pointer
|
||||
}
|
||||
mLock.unlock();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2128,6 +2141,7 @@ void LLViewerMediaImpl::setMute(bool mute)
|
|||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::updateVolume()
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE_VOLUME);
|
||||
if(mMediaSource)
|
||||
{
|
||||
// always scale the volume by the global media volume
|
||||
|
|
@ -2860,202 +2874,262 @@ static LLTrace::BlockTimerStatHandle FTM_MEDIA_SET_SUBIMAGE("Set Subimage");
|
|||
void LLViewerMediaImpl::update()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_DO_UPDATE);
|
||||
if(mMediaSource == NULL)
|
||||
{
|
||||
if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
|
||||
{
|
||||
// This media source should not be loaded.
|
||||
}
|
||||
else if(mPriority <= LLPluginClassMedia::PRIORITY_SLIDESHOW)
|
||||
{
|
||||
// Don't load new instances that are at PRIORITY_SLIDESHOW or below. They're just kept around to preserve state.
|
||||
}
|
||||
if(mMediaSource == NULL)
|
||||
{
|
||||
if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
|
||||
{
|
||||
// This media source should not be loaded.
|
||||
}
|
||||
else if(mPriority <= LLPluginClassMedia::PRIORITY_SLIDESHOW)
|
||||
{
|
||||
// Don't load new instances that are at PRIORITY_SLIDESHOW or below. They're just kept around to preserve state.
|
||||
}
|
||||
else if (!mMimeProbe.expired())
|
||||
{
|
||||
// this media source is doing a MIME type probe -- don't try loading it again.
|
||||
}
|
||||
else
|
||||
{
|
||||
// This media may need to be loaded.
|
||||
if(sMediaCreateTimer.hasExpired())
|
||||
{
|
||||
LL_DEBUGS("PluginPriority") << this << ": creating media based on timer expiration" << LL_ENDL;
|
||||
createMediaSource();
|
||||
sMediaCreateTimer.setTimerExpirySec(LLVIEWERMEDIA_CREATE_DELAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("PluginPriority") << this << ": NOT creating media (waiting on timer)" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
updateVolume();
|
||||
{
|
||||
// this media source is doing a MIME type probe -- don't try loading it again.
|
||||
}
|
||||
else
|
||||
{
|
||||
// This media may need to be loaded.
|
||||
if(sMediaCreateTimer.hasExpired())
|
||||
{
|
||||
LL_DEBUGS("PluginPriority") << this << ": creating media based on timer expiration" << LL_ENDL;
|
||||
createMediaSource();
|
||||
sMediaCreateTimer.setTimerExpirySec(LLVIEWERMEDIA_CREATE_DELAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("PluginPriority") << this << ": NOT creating media (waiting on timer)" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
updateVolume();
|
||||
|
||||
// TODO: this is updated every frame - is this bad?
|
||||
// Removing this as part of the post viewer64 media update
|
||||
// Removed as not implemented in CEF embedded browser
|
||||
// See MAINT-8194 for a more fuller description
|
||||
// updateJavascriptObject();
|
||||
}
|
||||
// TODO: this is updated every frame - is this bad?
|
||||
// Removing this as part of the post viewer64 media update
|
||||
// Removed as not implemented in CEF embedded browser
|
||||
// See MAINT-8194 for a more fuller description
|
||||
// updateJavascriptObject();
|
||||
}
|
||||
|
||||
|
||||
if(mMediaSource == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(mMediaSource == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure a navigate doesn't happen during the idle -- it can cause mMediaSource to get destroyed, which can cause a crash.
|
||||
setNavigateSuspended(true);
|
||||
// Make sure a navigate doesn't happen during the idle -- it can cause mMediaSource to get destroyed, which can cause a crash.
|
||||
setNavigateSuspended(true);
|
||||
|
||||
mMediaSource->idle();
|
||||
mMediaSource->idle();
|
||||
|
||||
setNavigateSuspended(false);
|
||||
setNavigateSuspended(false);
|
||||
|
||||
if(mMediaSource == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(mMediaSource == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(mMediaSource->isPluginExited())
|
||||
{
|
||||
resetPreviousMediaState();
|
||||
destroyMediaSource();
|
||||
return;
|
||||
}
|
||||
if(mMediaSource->isPluginExited())
|
||||
{
|
||||
resetPreviousMediaState();
|
||||
destroyMediaSource();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!mMediaSource->textureValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!mMediaSource->textureValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(mSuspendUpdates || !mVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(mSuspendUpdates || !mVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerMediaTexture* placeholder_image = updatePlaceholderImage();
|
||||
|
||||
LLViewerMediaTexture* media_tex;
|
||||
U8* data;
|
||||
S32 data_width;
|
||||
S32 data_height;
|
||||
S32 x_pos;
|
||||
S32 y_pos;
|
||||
S32 width;
|
||||
S32 height;
|
||||
|
||||
if(placeholder_image)
|
||||
{
|
||||
LLRect dirty_rect;
|
||||
|
||||
// Since we're updating this texture, we know it's playing. Tell the texture to do its replacement magic so it gets rendered.
|
||||
placeholder_image->setPlaying(TRUE);
|
||||
|
||||
if(mMediaSource->getDirty(&dirty_rect))
|
||||
{
|
||||
// Constrain the dirty rect to be inside the texture
|
||||
S32 x_pos = llmax(dirty_rect.mLeft, 0);
|
||||
S32 y_pos = llmax(dirty_rect.mBottom, 0);
|
||||
S32 width = llmin(dirty_rect.mRight, placeholder_image->getWidth()) - x_pos;
|
||||
S32 height = llmin(dirty_rect.mTop, placeholder_image->getHeight()) - y_pos;
|
||||
|
||||
if(width > 0 && height > 0)
|
||||
{
|
||||
|
||||
U8* data = NULL;
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media get data"); //LL_RECORD_BLOCK_TIME(FTM_MEDIA_GET_DATA);
|
||||
data = mMediaSource->getBitsData();
|
||||
}
|
||||
|
||||
if(data != NULL)
|
||||
{
|
||||
// Offset the pixels pointer to match x_pos and y_pos
|
||||
data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() );
|
||||
data += ( y_pos * mMediaSource->getTextureDepth() );
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media set subimage"); //LL_RECORD_BLOCK_TIME(FTM_MEDIA_SET_SUBIMAGE);
|
||||
placeholder_image->setSubImage(
|
||||
data,
|
||||
mMediaSource->getBitsWidth(),
|
||||
mMediaSource->getBitsHeight(),
|
||||
x_pos,
|
||||
y_pos,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mMediaSource->resetDirty();
|
||||
}
|
||||
}
|
||||
if (preMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height))
|
||||
{
|
||||
// Push update to worker thread
|
||||
auto main_queue = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
|
||||
if (main_queue)
|
||||
{
|
||||
mTextureUpdatePending = true;
|
||||
ref(); // protect texture from deletion while active on bg queue
|
||||
media_tex->ref();
|
||||
main_queue->postTo(
|
||||
mTexUpdateQueue, // Worker thread queue
|
||||
[=]() // work done on update worker thread
|
||||
{
|
||||
doMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height, true);
|
||||
},
|
||||
[=]() // callback to main thread
|
||||
{
|
||||
mTextureUpdatePending = false;
|
||||
media_tex->unref();
|
||||
unref();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
doMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height, false); // otherwise, update on main thread
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLViewerMediaImpl::preMediaTexUpdate(LLViewerMediaTexture*& media_tex, U8*& data, S32& data_width, S32& data_height, S32& x_pos, S32& y_pos, S32& width, S32& height)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
|
||||
|
||||
bool retval = false;
|
||||
|
||||
if (!mTextureUpdatePending)
|
||||
{
|
||||
media_tex = updateMediaImage();
|
||||
|
||||
if (media_tex && mMediaSource)
|
||||
{
|
||||
LLRect dirty_rect;
|
||||
S32 media_width = mMediaSource->getTextureWidth();
|
||||
S32 media_height = mMediaSource->getTextureHeight();
|
||||
//S32 media_depth = mMediaSource->getTextureDepth();
|
||||
|
||||
// Since we're updating this texture, we know it's playing. Tell the texture to do its replacement magic so it gets rendered.
|
||||
media_tex->setPlaying(TRUE);
|
||||
|
||||
if (mMediaSource->getDirty(&dirty_rect))
|
||||
{
|
||||
// Constrain the dirty rect to be inside the texture
|
||||
x_pos = llmax(dirty_rect.mLeft, 0);
|
||||
y_pos = llmax(dirty_rect.mBottom, 0);
|
||||
width = llmin(dirty_rect.mRight, media_width) - x_pos;
|
||||
height = llmin(dirty_rect.mTop, media_height) - y_pos;
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
data = mMediaSource->getBitsData();
|
||||
data_width = mMediaSource->getWidth();
|
||||
data_height = mMediaSource->getHeight();
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
// data is ready to be copied to GL
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
|
||||
mMediaSource->resetDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* data, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool sync)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
|
||||
mLock.lock(); // don't allow media source tear-down during update
|
||||
|
||||
// wrap "data" in an LLImageRaw but do NOT make a copy
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(data, media_tex->getWidth(), media_tex->getHeight(), media_tex->getComponents(), true);
|
||||
|
||||
// Allocate GL texture based on LLImageRaw but do NOT copy to GL
|
||||
media_tex->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER, true);
|
||||
|
||||
// copy just the subimage covered by the image raw to GL
|
||||
media_tex->setSubImage(data, data_width, data_height, x_pos, y_pos, width, height, sync);
|
||||
media_tex->getGLTexture()->syncToMainThread();
|
||||
|
||||
// release the data pointer before freeing raw so LLImageRaw destructor doesn't
|
||||
// free memory at data pointer
|
||||
raw->releaseData();
|
||||
|
||||
mLock.unlock();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::updateImagesMediaStreams()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
|
||||
LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage()
|
||||
{
|
||||
// if(mTextureId.isNull())
|
||||
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
|
||||
if ( (mTextureId.isNull()) || ((LLViewerFetchedTexture::sDefaultDiffuseImagep.notNull()) && (LLViewerFetchedTexture::sDefaultDiffuseImagep->getID() == mTextureId)) )
|
||||
// [/SL:KB]
|
||||
{
|
||||
// The code that created this instance will read from the plugin's bits.
|
||||
return NULL;
|
||||
}
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
|
||||
if (!mMediaSource)
|
||||
{
|
||||
return nullptr; // not ready for updating
|
||||
}
|
||||
|
||||
LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mTextureId );
|
||||
llassert(!mTextureId.isNull());
|
||||
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
|
||||
if (LLViewerFetchedTexture::sDefaultDiffuseImagep.notNull() && LLViewerFetchedTexture::sDefaultDiffuseImagep->getID() == mTextureId)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
// [/SL:KB]
|
||||
LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture( mTextureId );
|
||||
|
||||
if ( mNeedsNewTexture
|
||||
|| media_tex->getUseMipMaps()
|
||||
|| (media_tex->getWidth() != mMediaSource->getTextureWidth())
|
||||
|| (media_tex->getHeight() != mMediaSource->getTextureHeight())
|
||||
|| (mTextureUsedWidth != mMediaSource->getWidth())
|
||||
|| (mTextureUsedHeight != mMediaSource->getHeight())
|
||||
)
|
||||
{
|
||||
LL_DEBUGS("Media") << "initializing media placeholder" << LL_ENDL;
|
||||
LL_DEBUGS("Media") << "movie image id " << mTextureId << LL_ENDL;
|
||||
|
||||
if (mNeedsNewTexture
|
||||
|| placeholder_image->getUseMipMaps()
|
||||
|| (placeholder_image->getWidth() != mMediaSource->getTextureWidth())
|
||||
|| (placeholder_image->getHeight() != mMediaSource->getTextureHeight())
|
||||
|| (mTextureUsedWidth != mMediaSource->getWidth())
|
||||
|| (mTextureUsedHeight != mMediaSource->getHeight())
|
||||
)
|
||||
{
|
||||
LL_DEBUGS("Media") << "initializing media placeholder" << LL_ENDL;
|
||||
LL_DEBUGS("Media") << "movie image id " << mTextureId << LL_ENDL;
|
||||
int texture_width = mMediaSource->getTextureWidth();
|
||||
int texture_height = mMediaSource->getTextureHeight();
|
||||
int texture_depth = mMediaSource->getTextureDepth();
|
||||
|
||||
int texture_width = mMediaSource->getTextureWidth();
|
||||
int texture_height = mMediaSource->getTextureHeight();
|
||||
int texture_depth = mMediaSource->getTextureDepth();
|
||||
// MEDIAOPT: check to see if size actually changed before doing work
|
||||
media_tex->destroyGLTexture();
|
||||
// MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
|
||||
media_tex->reinit(FALSE); // probably not needed
|
||||
|
||||
// MEDIAOPT: check to see if size actually changed before doing work
|
||||
placeholder_image->destroyGLTexture();
|
||||
// MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
|
||||
placeholder_image->reinit(FALSE); // probably not needed
|
||||
// MEDIAOPT: seems insane that we actually have to make an imageraw then
|
||||
// immediately discard it
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth);
|
||||
// Clear the texture to the background color, ignoring alpha.
|
||||
// convert background color channels from [0.0, 1.0] to [0, 255];
|
||||
raw->clear(int(mBackgroundColor.mV[VX] * 255.0f), int(mBackgroundColor.mV[VY] * 255.0f), int(mBackgroundColor.mV[VZ] * 255.0f), 0xff);
|
||||
|
||||
// MEDIAOPT: seems insane that we actually have to make an imageraw then
|
||||
// immediately discard it
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth);
|
||||
// Clear the texture to the background color, ignoring alpha.
|
||||
// convert background color channels from [0.0, 1.0] to [0, 255];
|
||||
raw->clear(int(mBackgroundColor.mV[VX] * 255.0f), int(mBackgroundColor.mV[VY] * 255.0f), int(mBackgroundColor.mV[VZ] * 255.0f), 0xff);
|
||||
int discard_level = 0;
|
||||
// ask media source for correct GL image format constants
|
||||
media_tex->setExplicitFormat(mMediaSource->getTextureFormatInternal(),
|
||||
mMediaSource->getTextureFormatPrimary(),
|
||||
mMediaSource->getTextureFormatType(),
|
||||
mMediaSource->getTextureFormatSwapBytes());
|
||||
|
||||
// ask media source for correct GL image format constants
|
||||
placeholder_image->setExplicitFormat(mMediaSource->getTextureFormatInternal(),
|
||||
mMediaSource->getTextureFormatPrimary(),
|
||||
mMediaSource->getTextureFormatType(),
|
||||
mMediaSource->getTextureFormatSwapBytes());
|
||||
int discard_level = 0;
|
||||
media_tex->createGLTexture(discard_level, raw);
|
||||
|
||||
placeholder_image->createGLTexture(discard_level, raw);
|
||||
// MEDIAOPT: set this dynamically on play/stop
|
||||
// FIXME
|
||||
// media_tex->mIsMediaTexture = true;
|
||||
mNeedsNewTexture = false;
|
||||
|
||||
// MEDIAOPT: set this dynamically on play/stop
|
||||
// FIXME
|
||||
// placeholder_image->mIsMediaTexture = true;
|
||||
mNeedsNewTexture = false;
|
||||
|
||||
// If the amount of the texture being drawn by the media goes down in either width or height,
|
||||
// recreate the texture to avoid leaving parts of the old image behind.
|
||||
mTextureUsedWidth = mMediaSource->getWidth();
|
||||
mTextureUsedHeight = mMediaSource->getHeight();
|
||||
}
|
||||
|
||||
return placeholder_image;
|
||||
// If the amount of the texture being drawn by the media goes down in either width or height,
|
||||
// recreate the texture to avoid leaving parts of the old image behind.
|
||||
mTextureUsedWidth = mMediaSource->getWidth();
|
||||
mTextureUsedHeight = mMediaSource->getHeight();
|
||||
}
|
||||
return media_tex;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ public:
|
|||
U8 media_loop);
|
||||
|
||||
~LLViewerMediaImpl();
|
||||
|
||||
|
||||
// Override inherited version from LLViewerMediaEventEmitter
|
||||
virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event);
|
||||
|
||||
|
|
@ -266,6 +266,8 @@ public:
|
|||
void scaleTextureCoords(const LLVector2& texture_coords, S32 *x, S32 *y);
|
||||
|
||||
void update();
|
||||
bool preMediaTexUpdate(LLViewerMediaTexture*& media_tex, U8*& data, S32& data_width, S32& data_height, S32& x_pos, S32& y_pos, S32& width, S32& height);
|
||||
void doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* data, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool sync);
|
||||
void updateImagesMediaStreams();
|
||||
LLUUID getMediaTextureID() const;
|
||||
|
||||
|
|
@ -427,6 +429,7 @@ private:
|
|||
private:
|
||||
// a single media url with some data and an impl.
|
||||
boost::shared_ptr<LLPluginClassMedia> mMediaSource;
|
||||
LLMutex mLock;
|
||||
F64 mZoomFactor;
|
||||
LLUUID mTextureId;
|
||||
bool mMovieImageHasMips;
|
||||
|
|
@ -446,6 +449,7 @@ private:
|
|||
S32 mTextureUsedWidth;
|
||||
S32 mTextureUsedHeight;
|
||||
bool mSuspendUpdates;
|
||||
bool mTextureUpdatePending = false;
|
||||
bool mVisible;
|
||||
ECursorType mLastSetCursor;
|
||||
EMediaNavState mMediaNavState;
|
||||
|
|
@ -479,7 +483,7 @@ private:
|
|||
LLNotificationPtr mNotification;
|
||||
bool mCleanBrowser; // force the creation of a clean browsing target with full options enabled
|
||||
static std::vector<std::string> sMimeTypesFailed;
|
||||
|
||||
LLPointer<LLImageRaw> mRawImage; //backing buffer for texture updates
|
||||
private:
|
||||
BOOL mIsUpdated ;
|
||||
std::list< LLVOVolume* > mObjectList ;
|
||||
|
|
@ -489,7 +493,10 @@ private:
|
|||
bool mCanceling;
|
||||
|
||||
private:
|
||||
LLViewerMediaTexture *updatePlaceholderImage();
|
||||
LLViewerMediaTexture *updateMediaImage();
|
||||
LL::WorkQueue::weak_t mMainQueue;
|
||||
LL::WorkQueue::weak_t mTexUpdateQueue;
|
||||
|
||||
};
|
||||
|
||||
#endif // LLVIEWERMEDIA_H
|
||||
|
|
|
|||
|
|
@ -2167,12 +2167,12 @@ LLViewerWindow::LLViewerWindow(const Params& p)
|
|||
|
||||
// Init the image list. Must happen after GL is initialized and before the images that
|
||||
// LLViewerWindow needs are requested.
|
||||
LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreaded"));
|
||||
LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreaded"));
|
||||
gTextureList.init();
|
||||
LLViewerTextureManager::init() ;
|
||||
gBumpImageList.init();
|
||||
|
||||
// Create container for all sub-views
|
||||
// Create container for all sub-views
|
||||
LLView::Params rvp;
|
||||
rvp.name("root");
|
||||
rvp.rect(mWindowRectScaled);
|
||||
|
|
@ -2702,7 +2702,7 @@ void LLViewerWindow::shutdownGL()
|
|||
|
||||
LLViewerTextureManager::cleanup() ;
|
||||
SUBSYSTEM_CLEANUP(LLImageGL) ;
|
||||
|
||||
|
||||
LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ;
|
||||
|
||||
LL_INFOS() << "Cleaning up select manager" << LL_ENDL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue