Merged in revert-16418 (pull request #854)
Revert SL-16418 commits Approved-by: Michael Pohoreskimeow-7.2.2
commit
e6d44588d0
|
|
@ -925,73 +925,47 @@ bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
|
|||
|
||||
void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
S8 components = getComponents();
|
||||
llassert( components > 0 && components <= 4 );
|
||||
llassert( getComponents() <= 4 );
|
||||
// This is fairly bogus, but it'll do for now.
|
||||
if (isBufferInvalid())
|
||||
{
|
||||
LL_WARNS() << "Invalid image buffer" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// This is fairly bogus, but it'll do for now.
|
||||
if (isBufferInvalid())
|
||||
{
|
||||
LL_WARNS() << "Invalid image buffer" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (components)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
U8 *dst = getData();
|
||||
S32 count = getWidth() * getHeight();
|
||||
llassert(count == getDataSize());
|
||||
std::fill_n(dst, count, r);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
U16 *dst = (U16 *)getData();
|
||||
S32 count = getWidth() * getHeight();
|
||||
llassert(count == getDataSize() / 2);
|
||||
#ifdef LL_LITTLE_ENDIAN
|
||||
U16 val = (U16)(r | g << 8);
|
||||
#else
|
||||
U16 val = (U16)(r << 8 | g);
|
||||
#endif
|
||||
std::fill_n(dst, count, val);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
U8 *dst = getData();
|
||||
S32 count = getWidth() * getHeight();
|
||||
llassert(count == getDataSize() / 3);
|
||||
for (S32 i = 0; i < count; i++)
|
||||
{
|
||||
*dst++ = r;
|
||||
*dst++ = g;
|
||||
*dst++ = b;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
U32 *dst = (U32 *)getData();
|
||||
S32 count = getWidth() * getHeight();
|
||||
llassert(count == getDataSize() / 4);
|
||||
#ifdef LL_LITTLE_ENDIAN
|
||||
U32 val = (U32)(r | g << 8 | b << 16 | a << 24);
|
||||
#else
|
||||
U32 val = (U32)(r << 24 | g << 16 | b << 8 | a);
|
||||
#endif
|
||||
std::fill_n(dst, count, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
U8 *pos = getData();
|
||||
U32 x, y;
|
||||
for (x = 0; x < getWidth(); x++)
|
||||
{
|
||||
for (y = 0; y < getHeight(); y++)
|
||||
{
|
||||
*pos = r;
|
||||
pos++;
|
||||
if (getComponents() == 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*pos = g;
|
||||
pos++;
|
||||
if (getComponents() == 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*pos = b;
|
||||
pos++;
|
||||
if (getComponents() == 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*pos = a;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reverses the order of the rows in the image
|
||||
void LLImageRaw::verticalFlip()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
S32 row_bytes = getWidth() * getComponents();
|
||||
llassert(row_bytes > 0);
|
||||
std::vector<U8> line_buffer(row_bytes);
|
||||
|
|
|
|||
|
|
@ -1215,8 +1215,9 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
|
||||
{ //GL_ALPHA is deprecated, convert to RGBA
|
||||
use_scratch = true;
|
||||
scratch = new U32[width * height];
|
||||
|
||||
U32 pixel_count = (U32)(width * height);
|
||||
scratch = new U32[pixel_count];
|
||||
for (U32 i = 0; i < pixel_count; i++)
|
||||
{
|
||||
U8* pix = (U8*)&scratch[i];
|
||||
|
|
@ -1231,8 +1232,9 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE)
|
||||
{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
|
||||
use_scratch = true;
|
||||
scratch = new U32[width * height];
|
||||
|
||||
U32 pixel_count = (U32)(width * height);
|
||||
scratch = new U32[pixel_count];
|
||||
for (U32 i = 0; i < pixel_count; i++)
|
||||
{
|
||||
U8 lum = ((U8*)pixels)[i * 2 + 0];
|
||||
|
|
@ -1250,8 +1252,9 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
|
||||
{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
|
||||
use_scratch = true;
|
||||
scratch = new U32[width * height];
|
||||
|
||||
U32 pixel_count = (U32)(width * height);
|
||||
scratch = new U32[pixel_count];
|
||||
for (U32 i = 0; i < pixel_count; i++)
|
||||
{
|
||||
U8 lum = ((U8*)pixels)[i];
|
||||
|
|
@ -1311,7 +1314,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
}
|
||||
stop_glerror();
|
||||
|
||||
if (scratch) delete[] scratch;
|
||||
if (use_scratch)
|
||||
{
|
||||
delete[] scratch;
|
||||
}
|
||||
}
|
||||
|
||||
//create an empty GL texture: just create a texture name
|
||||
|
|
@ -1465,49 +1471,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
return createGLTexture(discard_level, rawdata, FALSE, usename);
|
||||
}
|
||||
|
||||
// Create a new GL name and allocate tex storage (unitialized) for it
|
||||
// Used to break resource contention stall in background media tex updates
|
||||
void LLImageGL::allocNewTexName()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (on_main_thread()) return; // Should only be called on bg update thread
|
||||
if (!mGLTextureCreated) return;
|
||||
if (0 != mNewTexName) return; // only 1 rename in flight at a time
|
||||
|
||||
generateTextures(1, &mNewTexName); // create new GL name
|
||||
|
||||
mHasMipMaps = false; // Media textures aren't mipped
|
||||
mMipLevels = 0;
|
||||
// Set state to match current
|
||||
gGL.getTexUnit(0)->bind(this, false, false, mNewTexName);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WIDTH, mWidth);
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_HEIGHT, mHeight);
|
||||
gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
|
||||
|
||||
setManualImage(mTarget, 0, mFormatInternal, mWidth, mHeight, mFormatPrimary, mFormatType,
|
||||
(GLvoid *) nullptr, mAllowCompression);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(mBindTarget);
|
||||
|
||||
mLastBindTime = sLastFrameTime;
|
||||
}
|
||||
|
||||
// Delete no-longer-needed GL tex name (on main thread)
|
||||
void LLImageGL::swapTexName()
|
||||
{
|
||||
if (mNewTexName)
|
||||
{
|
||||
deleteTextures(1, &mTexName);
|
||||
mTexName = mNewTexName;
|
||||
mNewTexName = 0;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips /* = FALSE */, S32 usename /* = 0 */)
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
checkActiveThread();
|
||||
|
|
@ -1751,14 +1715,6 @@ void LLImageGL::destroyGLTexture()
|
|||
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
|
||||
|
|
|
|||
|
|
@ -109,17 +109,15 @@ public:
|
|||
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
|
||||
|
||||
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 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);
|
||||
void setImage(const LLImageRaw* imageraw);
|
||||
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 setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
|
||||
void allocNewTexName();
|
||||
void swapTexName();
|
||||
|
||||
|
||||
// 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();
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#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"
|
||||
|
|
@ -79,9 +78,6 @@
|
|||
#include <boost/bind.hpp> // for SkinFolder listener
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
// Statics
|
||||
bool LLMediaTextureUpdateThread::sEnabled = false;
|
||||
|
||||
class LLMediaFilePicker : public LLFilePickerThread // deletes itself when done
|
||||
{
|
||||
public:
|
||||
|
|
@ -639,7 +635,6 @@ 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");
|
||||
|
|
@ -1595,8 +1590,6 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
|
|||
media_tex->setMediaImpl();
|
||||
}
|
||||
|
||||
mMainQueue = LL::WorkQueue::getInstance("mainloop");
|
||||
mTexUpdateQueue = LL::WorkQueue::getInstance("LLMediaTextureUpdate"); // Share work queue with tex loader.
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1610,25 +1603,6 @@ LLViewerMediaImpl::~LLViewerMediaImpl()
|
|||
remove_media_impl(this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//static
|
||||
void LLViewerMediaImpl::initClass(LLWindow* window, bool multi_threaded /* = false */)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
if (multi_threaded)
|
||||
{
|
||||
LLMediaTextureUpdateThread::createInstance(window);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//static
|
||||
void LLViewerMediaImpl::cleanupClass()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LLMediaTextureUpdateThread::deleteSingleton();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::emitEvent(LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
|
||||
{
|
||||
|
|
@ -1702,13 +1676,11 @@ 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();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2115,7 +2087,6 @@ 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
|
||||
|
|
@ -2828,248 +2799,199 @@ 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;
|
||||
}
|
||||
|
||||
// Push update to worker thread
|
||||
auto main_queue = LLMediaTextureUpdateThread::sEnabled ? mMainQueue.lock() : nullptr;
|
||||
ref(); // protect texture from deletion while active on bg queue
|
||||
if (main_queue)
|
||||
{
|
||||
main_queue->postTo(
|
||||
mTexUpdateQueue, // Worker thread queue
|
||||
[this]() // work done on update worker thread
|
||||
{
|
||||
doMediaTexUpdate();
|
||||
},
|
||||
[this]() // callback to main thread
|
||||
{
|
||||
endMediaTexUpdate();
|
||||
unref();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
doMediaTexUpdate(); // otherwise, update on main thread
|
||||
unref();
|
||||
}
|
||||
LLViewerMediaTexture* placeholder_image = updatePlaceholderImage();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::doMediaTexUpdate()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
|
||||
mLock.lock(); // don't allow media source tear-down during update
|
||||
|
||||
LLViewerMediaTexture* 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
|
||||
S32 x_pos = llmax(dirty_rect.mLeft, 0);
|
||||
S32 y_pos = llmax(dirty_rect.mBottom, 0);
|
||||
S32 width = llmin(dirty_rect.mRight, media_width) - x_pos;
|
||||
S32 height = llmin(dirty_rect.mTop, media_height) - y_pos;
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
U8* data = NULL;
|
||||
S32 data_width = mMediaSource->getBitsWidth();
|
||||
S32 data_height = mMediaSource->getBitsHeight();
|
||||
data = mMediaSource->getBitsData();
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
// Offset the pixels pointer to match x_pos and y_pos
|
||||
data += (x_pos * media_depth * data_width);
|
||||
data += (y_pos * media_depth);
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media set subimage"); //LL_RECORD_BLOCK_TIME(FTM_MEDIA_SET_SUBIMAGE);
|
||||
media_tex->setSubImage(
|
||||
data,
|
||||
data_width,
|
||||
data_height,
|
||||
x_pos,
|
||||
y_pos,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mMediaSource->resetDirty();
|
||||
}
|
||||
}
|
||||
mLock.unlock();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// runs on main thread, but only called when bg thread updates are active
|
||||
void LLViewerMediaImpl::endMediaTexUpdate()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
|
||||
LLViewerMediaTexture* base_image = LLViewerTextureManager::findMediaTexture(mTextureId);
|
||||
llassert(base_image);
|
||||
|
||||
LLImageGL* image = base_image->getGLTexture();
|
||||
image->swapTexName(); // retire old GL name
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void LLViewerMediaImpl::updateImagesMediaStreams()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage()
|
||||
LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
|
||||
if (!mMediaSource)
|
||||
{
|
||||
return nullptr; // not ready for updating
|
||||
}
|
||||
if(mTextureId.isNull())
|
||||
{
|
||||
// The code that created this instance will read from the plugin's bits.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
llassert(!mTextureId.isNull());
|
||||
LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture( mTextureId );
|
||||
|
||||
// if on bg thread, create new GL tex image resource to avoid resource contention
|
||||
if (!on_main_thread())
|
||||
{
|
||||
LLImageGL* image = media_tex->getGLTexture();
|
||||
image->allocNewTexName();
|
||||
}
|
||||
LLViewerMediaTexture* placeholder_image = 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 media_tex;
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3998,30 +3920,3 @@ bool LLViewerMediaImpl::isObjectInAgentParcel(LLVOVolume *obj)
|
|||
{
|
||||
return (LLViewerParcelMgr::getInstance()->inAgentParcel(obj->getPositionGlobal()));
|
||||
}
|
||||
|
||||
LLMediaTextureUpdateThread::LLMediaTextureUpdateThread(LLWindow* window)
|
||||
// We want exactly one thread, of moderate capacity: there are likely only a handful
|
||||
// of media texture frames in-flight at any one time
|
||||
: ThreadPool("LLMediaTextureUpdate", 1, 4096)
|
||||
, mWindow(window)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
sEnabled = true;
|
||||
mFinished = false;
|
||||
|
||||
mContext = mWindow->createSharedContext();
|
||||
ThreadPool::start();
|
||||
}
|
||||
|
||||
void LLMediaTextureUpdateThread::run()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
// We must perform setup on this thread before actually servicing our
|
||||
// WorkQueue, likewise cleanup afterwards.
|
||||
mWindow->makeContextCurrent(mContext);
|
||||
gGL.init();
|
||||
ThreadPool::run();
|
||||
LLMediaTextureUpdateThread::sEnabled = false;
|
||||
gGL.shutdown();
|
||||
mWindow->destroySharedContext(mContext);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,10 +197,7 @@ public:
|
|||
U8 media_loop);
|
||||
|
||||
~LLViewerMediaImpl();
|
||||
|
||||
static void initClass(LLWindow* window, bool multi_threaded = false);
|
||||
static void cleanupClass();
|
||||
|
||||
|
||||
// Override inherited version from LLViewerMediaEventEmitter
|
||||
virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event);
|
||||
|
||||
|
|
@ -269,8 +266,6 @@ public:
|
|||
void scaleTextureCoords(const LLVector2& texture_coords, S32 *x, S32 *y);
|
||||
|
||||
void update();
|
||||
void doMediaTexUpdate();
|
||||
void endMediaTexUpdate();
|
||||
void updateImagesMediaStreams();
|
||||
LLUUID getMediaTextureID() const;
|
||||
|
||||
|
|
@ -432,7 +427,6 @@ 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;
|
||||
|
|
@ -495,35 +489,7 @@ private:
|
|||
bool mCanceling;
|
||||
|
||||
private:
|
||||
LLViewerMediaTexture *updateMediaImage();
|
||||
LL::WorkQueue::weak_t mMainQueue;
|
||||
LL::WorkQueue::weak_t mTexUpdateQueue;
|
||||
|
||||
LLViewerMediaTexture *updatePlaceholderImage();
|
||||
};
|
||||
|
||||
// Define a worker thread pool for media updates (ref LLImageGLThread)
|
||||
class LLMediaTextureUpdateThread : public LLSimpleton<LLMediaTextureUpdateThread>, LL::ThreadPool
|
||||
{
|
||||
public:
|
||||
// follows gSavedSettings "RenderGLMultiThreaded"
|
||||
static bool sEnabled;
|
||||
|
||||
LLMediaTextureUpdateThread(LLWindow* window);
|
||||
|
||||
// post a function to be executed on the LLMediaTextureUpdateThread background thread
|
||||
template <typename CALLABLE>
|
||||
bool post(CALLABLE&& func)
|
||||
{
|
||||
return getQueue().postIfOpen(std::forward<CALLABLE>(func));
|
||||
}
|
||||
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
LLWindow* mWindow;
|
||||
void* mContext = nullptr;
|
||||
LLAtomicBool mFinished;
|
||||
};
|
||||
|
||||
|
||||
#endif // LLVIEWERMEDIA_H
|
||||
|
|
|
|||
|
|
@ -1629,6 +1629,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
|
|||
mNeedsCreateTexture = TRUE;
|
||||
if (preCreateTexture())
|
||||
{
|
||||
ref();
|
||||
#if LL_IMAGEGL_THREAD_CHECK
|
||||
//grab a copy of the raw image data to make sure it isn't modified pending texture creation
|
||||
U8* data = mRawImage->getData();
|
||||
|
|
@ -1642,7 +1643,6 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
|
|||
#endif
|
||||
mNeedsCreateTexture = TRUE;
|
||||
auto mainq = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
|
||||
ref(); // protect texture from deletion while active on bg queue
|
||||
if (mainq)
|
||||
{
|
||||
mainq->postTo(
|
||||
|
|
|
|||
|
|
@ -2027,9 +2027,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
|
|||
gTextureList.init();
|
||||
LLViewerTextureManager::init() ;
|
||||
gBumpImageList.init();
|
||||
|
||||
// Init Media texture worker queue
|
||||
LLViewerMediaImpl::initClass(mWindow, gSavedSettings.getBOOL("RenderGLMultiThreaded"));
|
||||
|
||||
// Create container for all sub-views
|
||||
LLView::Params rvp;
|
||||
|
|
@ -2419,8 +2416,7 @@ void LLViewerWindow::shutdownGL()
|
|||
|
||||
LLViewerTextureManager::cleanup() ;
|
||||
SUBSYSTEM_CLEANUP(LLImageGL) ;
|
||||
SUBSYSTEM_CLEANUP(LLViewerMediaImpl);
|
||||
|
||||
|
||||
LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ;
|
||||
|
||||
LL_INFOS() << "Cleaning up select manager" << LL_ENDL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue