Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion indra/llrender/llgltexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class LLGLTexture : public LLTexture
LLGLenum getPrimaryFormat() const;
bool getIsAlphaMask() const ;
LLTexUnit::eTextureType getTarget(void) const ;
bool getMask(const LLVector2 &tc);
virtual bool getMask(const LLVector2 &tc);
F32 getTimePassedSinceLastBound();
bool getMissed() const ;
bool isJustBound()const ;
Expand Down
4 changes: 2 additions & 2 deletions indra/media_plugins/cef/media_plugin_cef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
// SL-15560: Product team overruled my change to set the default
// embedded background color to match the floater background
// and set it to white
settings.background_color = 0xffffffff; // white
settings.background_color = 0x00000000; // transparent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line means the default background color will be #000000 (black) so pages that do not specify a background color will inherit a black background.

Is that what you intended?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was not the intention no, I must have forgot to change that doing some testing.

As for existing content, I did some testing and yeah any blank page that does not have a CSS set background does show as fully transparent.

I added a toggle in media general settings to toggle it per face, and it should be ready for a future server message if I did everything correctly.
For now the checkbox is session based for testing so it wont get set back to false from the server not knowing about it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonderful - thank you for your excellent contribution. We'll ask our product folk to look at it since it has some potential content impacts and once we get their blessing, we'll merge it in.

Thank you.


Comment on lines 654 to 658
settings.root_cache_path = mRootCachePath;
settings.cookies_enabled = mCookiesEnabled;
Expand Down Expand Up @@ -734,7 +734,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
message.setValueS32("default_width", 1024);
message.setValueS32("default_height", 1024);
message.setValueS32("depth", mDepth);
message.setValueU32("internalformat", GL_RGB);
message.setValueU32("internalformat", GL_RGBA);
message.setValueU32("format", GL_BGRA);
message.setValueU32("type", GL_UNSIGNED_BYTE);
message.setValueBoolean("coords_opengl", true);
Expand Down
51 changes: 50 additions & 1 deletion indra/newview/lltoolpie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,25 @@ bool LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType cli
return result;
}

// True if the pick landed on a media face at a fully transparent media
// pixel, so the pick should defer to whatever is visible behind it.
static bool is_transparent_media_pick(const LLPickInfo& pick)
{
LLViewerObject* objectp = pick.getObject();
if (!objectp || pick.mObjectFace < 0 || pick.mObjectFace >= objectp->getNumTEs())
{
return false;
}
const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
LLMediaEntry* mep = (tep && tep->hasMedia()) ? tep->getMediaData() : NULL;
if (!mep)
{
return false;
}
viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID());
return media_impl.notNull() && media_impl->isTransparentAt(pick.mUVCoords);
}

bool LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (mDoubleClickTimer.getStarted())
Expand All @@ -129,7 +148,13 @@ bool LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
// left mouse down always picks transparent (but see handleMouseUp).
// Also see LLToolPie::handleHover() - priorities are a bit different there.
// Todo: we need a more consistent set of rules to work with
if (transp_object == visible_object || !visible_object ||
if (transp_object != visible_object && is_transparent_media_pick(transparent_pick))
{
// The transparent pick went through a fully transparent media pixel,
// act on whatever is visible behind it (object, land, or nothing).
mPick = visible_pick;
}
else if (transp_object == visible_object || !visible_object ||
!transp_object) // avoid potential for null dereference below, don't make assumptions about behavior of pickImmediate
{
mPick = transparent_pick;
Expand Down Expand Up @@ -1666,6 +1691,14 @@ bool LLToolPie::handleMediaClick(const LLPickInfo& pick)

viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID());

if (media_impl.notNull() && media_impl->isTransparentAt(pick.mUVCoords))
{
// The click landed on a fully transparent part of the media, let it
// pass through to the world.
LLViewerMediaFocus::getInstance()->clearFocus();
return false;
}

if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
{
if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
Expand Down Expand Up @@ -1730,6 +1763,14 @@ bool LLToolPie::handleMediaDblClick(const LLPickInfo& pick)

viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID());

if (media_impl.notNull() && media_impl->isTransparentAt(pick.mUVCoords))
{
// The click landed on a fully transparent part of the media, let it
// pass through to the world.
LLViewerMediaFocus::getInstance()->clearFocus();
return false;
}

if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
{
if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
Expand Down Expand Up @@ -1785,6 +1826,14 @@ bool LLToolPie::handleMediaHover(const LLPickInfo& pick)
{
viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mep->getMediaID());

if (media_impl.notNull() && media_impl->isTransparentAt(pick.mUVCoords))
{
// Hovering over a fully transparent part of the media, treat it
// as normal in-world hover.
LLViewerMediaFocus::getInstance()->clearHover();
return false;
}

if(media_impl.notNull())
{
// Update media hover object
Expand Down
45 changes: 43 additions & 2 deletions indra/newview/llviewermedia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2350,6 +2350,47 @@ void LLViewerMediaImpl::scaleTextureCoords(const LLVector2& texture_coords, S32
*y -= (mMediaSource->getTextureHeight() - mMediaSource->getHeight());
}

//////////////////////////////////////////////////////////////////////////////////////////
bool LLViewerMediaImpl::isTransparentAt(const LLVector2& texture_coords)
{
if (!mMediaSource || !mMediaSource->textureValid())
{
return false;
}

// Only media with an alpha channel (BGRA) can have transparent areas.
const S32 depth = mMediaSource->getTextureDepth();
if (depth != 4)
{
return false;
}

const U8* pixels = mMediaSource->getBitsData();
if (!pixels)
{
return false;
}

S32 x, y;
scaleTextureCoords(texture_coords, &x, &y);

// scaleTextureCoords returns browser coordinates (y = 0 at the top), but
// plugins with coords_opengl write rows bottom-up in GL order into the
// shared buffer (dullahan's flip_pixels_y), so flip y to address the buffer.
if (mMediaSource->getTextureCoordsOpenGL())
{
y = mMediaSource->getHeight() - 1 - y;
}

const S32 buffer_width = mMediaSource->getBitsWidth();
if (x < 0 || y < 0 || x >= buffer_width || y >= mMediaSource->getBitsHeight())
{
return false;
}

return pixels[(y * buffer_width + x) * depth + 3] == 0;
}

//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseDown(const LLVector2& texture_coords, MASK mask, S32 button)
{
Expand Down Expand Up @@ -3172,9 +3213,9 @@ LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage()
// 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.
// Clear the texture to the background color with 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);
raw->clear(int(mBackgroundColor.mV[VX] * 255.0f), int(mBackgroundColor.mV[VY] * 255.0f), int(mBackgroundColor.mV[VZ] * 255.0f), 0x00);

// ask media source for correct GL image format constants
media_tex->setExplicitFormat(mMediaSource->getTextureFormatInternal(),
Expand Down
3 changes: 3 additions & 0 deletions indra/newview/llviewermedia.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ class LLViewerMediaImpl
void scrollWheel(const LLVector2& texture_coords, S32 scroll_x, S32 scroll_y, MASK mask);
void scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask);
void mouseCapture();
// True if the media pixel at the given texture coordinates is fully
// transparent, so mouse events can pass through to the world.
bool isTransparentAt(const LLVector2& texture_coords);

void navigateBack();
void navigateForward();
Expand Down
11 changes: 11 additions & 0 deletions indra/newview/llviewertexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3712,6 +3712,17 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()

return mMaxVirtualSize;
}

//virtual
bool LLViewerMediaTexture::getMask(const LLVector2 &tc)
{
if (mIsPlaying && mMediaImplp)
{
return !mMediaImplp->isTransparentAt(tc);
}

return LLViewerTexture::getMask(tc);
}
//----------------------------------------------------------------------------------------------
//end of LLViewerMediaTexture
//----------------------------------------------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions indra/newview/llviewertexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,10 @@ class LLViewerMediaTexture : public LLViewerTexture

/*virtual*/ F32 getMaxVirtualSize();

// Sample the live media pixel buffer so picks pass through fully
// transparent areas of the media.
/*virtual*/ bool getMask(const LLVector2 &tc);

private:
void switchTexture(U32 ch, LLFace* facep) ;
bool findFaces() ;
Expand Down
2 changes: 1 addition & 1 deletion indra/newview/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1780,7 +1780,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
bool alpha = color_alpha;
if (imagep)
{
alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
alpha = alpha || (imagep->getComponents() == 4) || (imagep->getComponents() == 2);
}

if (alpha && mat)
Expand Down
Loading