diff options
-rw-r--r-- | indra/llimage/llimage.cpp | 96 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 66 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 10 | ||||
-rw-r--r-- | indra/newview/llviewermedia.cpp | 427 | ||||
-rw-r--r-- | indra/newview/llviewermedia.h | 37 | ||||
-rw-r--r-- | indra/newview/llviewertexture.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llviewerwindow.cpp | 6 |
7 files changed, 214 insertions, 430 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index ba7ee0b465..15b07e5318 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -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 ); - - // This is fairly bogus, but it'll do for now. - if (isBufferInvalid()) - { - LL_WARNS() << "Invalid image buffer" << LL_ENDL; - return; - } + llassert( getComponents() <= 4 ); + // 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); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 4b4f071171..1e9b9f642e 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -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 diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index f311170823..d6f4b13a51 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -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(); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 6c04321539..63f57e81cc 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -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. } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1611,25 +1604,6 @@ LLViewerMediaImpl::~LLViewerMediaImpl() } ////////////////////////////////////////////////////////////////////////////////////////// -//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) { // Broadcast to observers using the superclass version @@ -2113,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 @@ -2826,252 +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; + } + LLViewerMediaTexture* placeholder_image = updatePlaceholderImage(); - // 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) - { - // replace GL name - //llassert(!mTextureId.isNull()); - //LLImageGL* base_image = LLViewerTextureManager::getMediaTexture(mTextureId)->getGLTexture(); - //GLuint retired_name = base_image->allocNew(); - 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(); - } -} + if(placeholder_image) + { + LLRect dirty_rect; -////////////////////////////////////////////////////////////////////////////////////////// -void LLViewerMediaImpl::doMediaTexUpdate() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; - LLViewerMediaTexture* media_tex = updateMediaImage(); + // 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 (media_tex && mMediaSource) - { - llassert(mMediaSource); - - LLRect dirty_rect; - S32 media_width = mMediaSource->getTextureWidth(); - S32 media_height = mMediaSource->getTextureHeight(); - S32 media_depth = mMediaSource->getTextureDepth(); + 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; - // 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(width > 0 && height > 0) + { - 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; + U8* data = NULL; + { + LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("media get data"); //LL_RECORD_BLOCK_TIME(FTM_MEDIA_GET_DATA); + data = mMediaSource->getBitsData(); + } - 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 * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() ); + data += ( y_pos * mMediaSource->getTextureDepth() ); - 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); - } - } + { + 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(); - } - } + mMediaSource->resetDirty(); + } + } } -////////////////////////////////////////////////////////////////////////////////////////// -// 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; - - 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: 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); - - // ask media source for correct GL image format constants - media_tex->setExplicitFormat(mMediaSource->getTextureFormatInternal(), - mMediaSource->getTextureFormatPrimary(), - mMediaSource->getTextureFormatType(), - mMediaSource->getTextureFormatSwapBytes()); - - int discard_level = 0; - media_tex->createGLTexture(discard_level, raw); - - // MEDIAOPT: set this dynamically on play/stop - // FIXME -// media_tex->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 (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(); + + // 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); + int discard_level = 0; + + // ask media source for correct GL image format constants + placeholder_image->setExplicitFormat(mMediaSource->getTextureFormatInternal(), + mMediaSource->getTextureFormatPrimary(), + mMediaSource->getTextureFormatType(), + mMediaSource->getTextureFormatSwapBytes()); + + placeholder_image->createGLTexture(discard_level, raw); + + // 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; } @@ -4000,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); -} diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 03a14421ff..71cec5125d 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -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; @@ -494,35 +489,7 @@ private: bool mCanceling; private: - LLViewerMediaTexture *updateMediaImage(); - LL::WorkQueue::weak_t mMainQueue; - LL::WorkQueue::weak_t mTexUpdateQueue; - -}; - -// 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; + LLViewerMediaTexture *updatePlaceholderImage(); }; - #endif // LLVIEWERMEDIA_H diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index ccf4c5bbec..5fed46f437 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -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( diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ba93f4f5f9..b9a5e90df0 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -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; |