Merge branch 'main' into DRTVWR-568

master
Callum Prentice 2022-12-12 11:13:10 -08:00
commit f7838ca17c
127 changed files with 2366 additions and 2534 deletions

78
.github/labeler.yaml vendored Normal file
View File

@ -0,0 +1,78 @@
llappearance:
- indra/llappearance/**/*
llaudio:
- indra/llaudio/**/*
llcharacter:
- indra/llcharacter/**/*
llcommon:
- indra/llcommon/**/*
llcorehttp:
- indra/llcorehttp/**/*
llcrashlogger:
- indra/llcrashlogger/**/*
llfilesystem:
- indra/llfilesystem/**/*
llimage:
- indra/llimage/**/*
llimagej2coj:
- indra/llimagej2coj/**/*
llinventory:
- indra/llinventory/**/*
llkdu:
- indra/llkdu/**/*
llmath:
- indra/llmath/**/*
llmeshoptimizer:
- indra/llmeshoptimizer/**/*
llmessage:
- indra/llmessage/**/*
llplugin:
- indra/llplugin/**/*
llprimitive:
- indra/llprimitive/**/*
llrender:
- indra/llrender/**/*
llui:
- indra/llui/**/*
llwindow:
- indra/llwindow/**/*
llxml:
- indra/llxml/**/*
cmake:
- '**/*.cmake'
- '**/*/cmake/*'
- '**/CMakeLists.txt'
python:
- '**/*.py'
c/cpp:
- '**/*.c'
- '**/*.cpp'
- '**/*.cxx'
- '**/*.h'
- '**/*.hpp'
- '**/*.hxx'
- '**/*.i'
- '**/*.inl'
- '**/*.y'

25
.github/workflows/cla.yaml vendored Normal file
View File

@ -0,0 +1,25 @@
name: Check CLA
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened, closed, synchronize]
jobs:
cla:
name: Check CLA
runs-on: ubuntu-latest
steps:
- name: CLA Assistant
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
uses: secondlife-3p/contributor-assistant@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN: ${{ secrets.SHARED_CLA_TOKEN }}
with:
branch: main
path-to-document: https://github.com/secondlife/cla/blob/master/CLA.md
path-to-signatures: signatures.json
remote-organization-name: secondlife
remote-repository-name: cla-signatures

15
.github/workflows/label.yaml vendored Normal file
View File

@ -0,0 +1,15 @@
name: Pull Request Labeler
on:
- pull_request_target
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
with:
configuration-path: .github/labeler.yaml
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -1,4 +1,8 @@
![Second Life Logo](doc/sl-logo.png)
<picture>
<source media="(prefers-color-scheme: dark)" srcset="doc/sl-logo-dark.png">
<source media="(prefers-color-scheme: light)" srcset="doc/sl-logo.png">
<img alt="Second Life Logo" src="doc/sl-logo.png">
</picture>
**[Second Life][] is a free 3D virtual world where users can create, connect and chat with others from around the
world.** This repository contains the source code for the official client.

View File

@ -184,9 +184,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ae90d19cdcddf539f6d0b41cab12f918</string>
<string>7b4aceaed511d44c4d1354b2162b59c7</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72773/702861/bugsplat-1.0.7.552580-darwin64-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107398/936936/bugsplat-1.0.7.576560-darwin64-576560.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -196,9 +196,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f5936eceb6a33ff0f1cc31996a40f29c</string>
<string>53918c7c74b943cdc0bb90caf9657a84</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72774/702905/bugsplat-3.6.0.8.552580-windows-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107400/936949/bugsplat-4.0.3.0.576560-windows-576560.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -208,16 +208,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>9cd940754e53e0670030b3da5ba8f373</string>
<string>19d6a55db101f02e7eb531daf3e8cfd1</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72775/702906/bugsplat-3.6.0.8.552580-windows64-552580.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107401/936948/bugsplat-.576560-windows64-576560.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>3.6.0.8.552580</string>
<string>4.0.3.0.576560</string>
</map>
<key>colladadom</key>
<map>
@ -612,9 +612,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>2c619c1bef969dc42b4f44a4651b314e</string>
<string>8de71c518c248d77f70f87ab5e9de732</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98369/869141/fmodstudio-2.02.06.570913-darwin64-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105828/925920/fmodstudio-2.02.06.575716-darwin64-575716.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -636,9 +636,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>875ccd8c1feec8ff03438d453371044b</string>
<string>2eea946ee7a572b748cec0c623ade3ef</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98371/869153/fmodstudio-2.02.06.570913-windows-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105830/925932/fmodstudio-2.02.06.575716-windows-575716.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -648,16 +648,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>5e402f4828741bce942e2ced318cd02a</string>
<string>483d6fd5d057b0a681bffef9b8b9d927</string>
<key>url</key>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/98372/869154/fmodstudio-2.02.06.570913-windows64-570913.tar.bz2</string>
<string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/105829/925931/fmodstudio-2.02.06.575716-windows64-575716.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.02.06.570913</string>
<string>2.02.06.575716</string>
</map>
<key>fontconfig</key>
<map>
@ -2701,9 +2701,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>1dda5fb3bb649b0ab5a93f22df7cb11e</string>
<string>2e8d817e7837dd6f4284b13fa3f5c15e</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/96998/862110/viewer_manager-3.0.569958-darwin64-569958.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104765/917714/viewer_manager-3.0.575083-darwin64-575083.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -2713,9 +2713,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>30d1386d0a6883d898fc56757a789b8b</string>
<string>3efa80faaf537e39a77218cd6efa9409</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/97002/862130/viewer_manager-3.0.569958-windows-569958.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104766/917721/viewer_manager-3.0.575083-windows-575083.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -2726,7 +2726,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>3.0.569958</string>
<string>3.0.575083</string>
</map>
<key>vlc-bin</key>
<map>
@ -2918,7 +2918,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>package_description</key>
<map>
<key>canonical_repo</key>
<string>https://bitbucket.org/lindenlab/viewer</string>
<string>https://github.com/secondlife/viewer</string>
<key>copyright</key>
<string>Copyright (c) 2020, Linden Research, Inc.</string>
<key>description</key>

502
doc/LGPL-license.txt Executable file
View File

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -282,6 +282,7 @@ Beq Janus
SL-11300
SL-15709
SL-16021
SL-18637
Beth Walcher
Bezilon Kasei
Biancaluce Robbiani

BIN
doc/sl-logo-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -95,7 +95,6 @@ set(llcommon_SOURCE_FILES
llsys.cpp
lltempredirect.cpp
llthread.cpp
llthreadlocalstorage.cpp
llthreadsafequeue.cpp
lltimer.cpp
lltrace.cpp

View File

@ -30,7 +30,6 @@
#include "llapr.h"
#include "llmutex.h"
#include "apr_dso.h"
#include "llthreadlocalstorage.h"
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
@ -54,7 +53,6 @@ void ll_init_apr()
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
}
LLThreadLocalPointerBase::initAllThreadLocalStorage();
gAPRInitialized = true;
}
@ -70,8 +68,6 @@ void ll_cleanup_apr()
LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
if (gAPRPoolp)
{
apr_pool_destroy(gAPRPoolp);

View File

@ -1,115 +0,0 @@
/**
* @file llthreadlocalstorage.cpp
* @author Richard
* @date 2013-1-11
* @brief implementation of thread local storage utility classes
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llthreadlocalstorage.h"
#include "llapr.h"
//
//LLThreadLocalPointerBase
//
bool LLThreadLocalPointerBase::sInitialized = false;
void LLThreadLocalPointerBase::set( void* value )
{
llassert(sInitialized && mThreadKey);
apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to set thread local data" << LL_ENDL;
}
}
void* LLThreadLocalPointerBase::get() const
{
// llassert(sInitialized);
void* ptr;
apr_status_t result =
apr_threadkey_private_get(&ptr, mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to get thread local data" << LL_ENDL;
}
return ptr;
}
void LLThreadLocalPointerBase::initStorage( )
{
apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL;
}
}
void LLThreadLocalPointerBase::destroyStorage()
{
if (sInitialized)
{
if (mThreadKey)
{
apr_status_t result = apr_threadkey_private_delete(mThreadKey);
if (result != APR_SUCCESS)
{
ll_apr_warn_status(result);
LL_ERRS() << "Failed to delete thread local data" << LL_ENDL;
}
}
}
}
//static
void LLThreadLocalPointerBase::initAllThreadLocalStorage()
{
if (!sInitialized)
{
for (auto& base : instance_snapshot())
{
base.initStorage();
}
sInitialized = true;
}
}
//static
void LLThreadLocalPointerBase::destroyAllThreadLocalStorage()
{
if (sInitialized)
{
//for (auto& base : instance_snapshot())
//{
// base.destroyStorage();
//}
sInitialized = false;
}
}

View File

@ -30,100 +30,6 @@
#include "llinstancetracker.h"
class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
{
public:
LLThreadLocalPointerBase()
: mThreadKey(NULL)
{
if (sInitialized)
{
initStorage();
}
}
LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
: mThreadKey(NULL)
{
if (sInitialized)
{
initStorage();
}
}
~LLThreadLocalPointerBase()
{
destroyStorage();
}
static void initAllThreadLocalStorage();
static void destroyAllThreadLocalStorage();
protected:
void set(void* value);
void* get() const;
void initStorage();
void destroyStorage();
protected:
struct apr_threadkey_t* mThreadKey;
static bool sInitialized;
};
template <typename T>
class LLThreadLocalPointer : public LLThreadLocalPointerBase
{
public:
LLThreadLocalPointer()
{}
explicit LLThreadLocalPointer(T* value)
{
set(value);
}
LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
: LLThreadLocalPointerBase(other)
{
set(other.get());
}
LL_FORCE_INLINE T* get() const
{
return (T*)LLThreadLocalPointerBase::get();
}
T* operator -> () const
{
return (T*)get();
}
T& operator*() const
{
return *(T*)get();
}
LLThreadLocalPointer<T>& operator = (T* value)
{
set((void*)value);
return *this;
}
bool operator ==(const T* other) const
{
if (!sInitialized) return false;
return get() == other;
}
bool isNull() const { return !sInitialized || get() == NULL; }
bool notNull() const { return sInitialized && get() != NULL; }
};
template<typename DERIVED_TYPE>
class LLThreadLocalSingletonPointer
{
@ -139,10 +45,10 @@ public:
}
private:
static LL_THREAD_LOCAL DERIVED_TYPE* sInstance;
static thread_local DERIVED_TYPE* sInstance;
};
template<typename DERIVED_TYPE>
LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
#endif // LL_LLTHREADLOCALSTORAGE_H

View File

@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description )
mDescription(description ? description : "")
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLTrace::get_thread_recorder().notNull())
if (LLTrace::get_thread_recorder() != NULL)
{
LL_ERRS() << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << LL_ENDL;
}

View File

@ -93,7 +93,7 @@ void AccumulatorBufferGroup::makeCurrent()
mStackTimers.makeCurrent();
mMemStats.makeCurrent();
ThreadRecorder* thread_recorder = get_thread_recorder().get();
ThreadRecorder* thread_recorder = get_thread_recorder();
AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
// update stacktimer parent pointers
for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++)

View File

@ -95,7 +95,7 @@ Recording::~Recording()
// allow recording destruction without thread recorder running,
// otherwise thread shutdown could crash if a recording outlives the thread recorder
// besides, recording construction and destruction is fine without a recorder...just don't attempt to start one
if (isStarted() && LLTrace::get_thread_recorder().notNull())
if (isStarted() && LLTrace::get_thread_recorder() != NULL)
{
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
}
@ -112,9 +112,9 @@ void Recording::update()
// must have
llassert(mActiveBuffers != NULL
&& LLTrace::get_thread_recorder().notNull());
&& LLTrace::get_thread_recorder() != NULL);
if(!mActiveBuffers->isCurrent())
if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
{
AccumulatorBufferGroup* buffers = mBuffers.write();
LLTrace::get_thread_recorder()->deactivate(buffers);
@ -144,7 +144,7 @@ void Recording::handleStart()
mSamplingTimer.reset();
mBuffers.setStayUnique(true);
// must have thread recorder running on this thread
llassert(LLTrace::get_thread_recorder().notNull());
llassert(LLTrace::get_thread_recorder() != NULL);
mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write());
#endif
}
@ -155,7 +155,7 @@ void Recording::handleStop()
#if LL_TRACE_ENABLED
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
// must have thread recorder running on this thread
llassert(LLTrace::get_thread_recorder().notNull());
llassert(LLTrace::get_thread_recorder() != NULL);
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
mActiveBuffers = NULL;
mBuffers.setStayUnique(false);
@ -1181,8 +1181,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth
PeriodicRecording& get_frame_recording()
{
static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
return *sRecording;
static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
return sRecording;
}
}

View File

@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder()
return sMasterThreadRecorder;
}
LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
ThreadRecorder*& get_thread_recorder_ptr()
{
static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder;
static thread_local ThreadRecorder* s_thread_recorder;
return s_thread_recorder;
}
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
ThreadRecorder* get_thread_recorder()
{
return get_thread_recorder_ptr();
}

View File

@ -32,7 +32,6 @@
#include "llmutex.h"
#include "lltraceaccumulators.h"
#include "llthreadlocalstorage.h"
namespace LLTrace
{
@ -92,7 +91,7 @@ namespace LLTrace
};
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder();
ThreadRecorder* get_thread_recorder();
void set_thread_recorder(ThreadRecorder*);
void set_master_thread_recorder(ThreadRecorder*);

View File

@ -5013,6 +5013,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
{
U16 index = mIndices[i];
if (index >= mNumVertices)
{
// invalid index
// replace with a valid index to avoid crashes
index = mNumVertices - 1;
mIndices[i] = index;
// Needs better logging
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;
}
LLVolumeFace::VertexData cv;
getVertexData(index, cv);
@ -5385,6 +5396,17 @@ bool LLVolumeFace::cacheOptimize()
U16 idx = mIndices[i];
U32 tri_idx = i / 3;
if (idx >= mNumVertices)
{
// invalid index
// replace with a valid index to avoid crashes
idx = mNumVertices - 1;
mIndices[i] = idx;
// Needs better logging
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;
}
vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx]));
vertex_data[idx].mIdx = idx;
triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]);

View File

@ -666,7 +666,6 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance()
char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock");
char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID");
char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel");
char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage");
char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats");
char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos");
char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit");
@ -1047,7 +1046,6 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS
char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter");
char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity");
char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket");
char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket");
char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal");
char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel");
char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing");
@ -1236,7 +1234,6 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get
char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease");
char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType");
char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply");
char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData");
char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage");
char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation");
char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection");

View File

@ -666,7 +666,6 @@ extern char const* const _PREHASH_GroupRolesCount;
extern char const* const _PREHASH_SimulatorBlock;
extern char const* const _PREHASH_GroupID;
extern char const* const _PREHASH_AgentVel;
extern char const* const _PREHASH_RequestImage;
extern char const* const _PREHASH_NetStats;
extern char const* const _PREHASH_AgentPos;
extern char const* const _PREHASH_AgentSit;
@ -1047,7 +1046,6 @@ extern char const* const _PREHASH_SortOrder;
extern char const* const _PREHASH_Hunter;
extern char const* const _PREHASH_SunAngVelocity;
extern char const* const _PREHASH_BinaryBucket;
extern char const* const _PREHASH_ImagePacket;
extern char const* const _PREHASH_StartGroupProposal;
extern char const* const _PREHASH_EnergyLevel;
extern char const* const _PREHASH_PriceForListing;

View File

@ -330,7 +330,10 @@ LLModel::EModelStatus load_face_from_dom_triangles(
// VFExtents change
face.mExtents[0].set(v[0], v[1], v[2]);
face.mExtents[1].set(v[0], v[1], v[2]);
point_map.clear();
verts.clear();
indices.clear();
point_map.clear();
}
}

View File

@ -57,6 +57,8 @@ public:
mutable std::vector<S32> mJointNums;
typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t;
matrix_list_t mInvBindMatrix;
// bones/joints position overrides
matrix_list_t mAlternateBindMatrix;
LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);

View File

@ -38,7 +38,8 @@ typedef enum e_chat_source_type
CHAT_SOURCE_AGENT = 1,
CHAT_SOURCE_OBJECT = 2,
CHAT_SOURCE_TELEPORT = 3,
CHAT_SOURCE_UNKNOWN = 4
CHAT_SOURCE_UNKNOWN = 4,
CHAT_SOURCE_REGION = 5,
} EChatSourceType;
typedef enum e_chat_type

View File

@ -203,11 +203,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
// it will work fine in case of decrease of space, but if we get more space or text
// becomes longer, label will fail to grow so reinit label's dimentions.
static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0);
LLRect label_rect = mLabel->getRect();
S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad;
label_rect.mRight = label_rect.mLeft + new_width;
mLabel->setRect(label_rect);
S32 new_width = rect.getWidth() - label_rect.mLeft;
mLabel->reshape(new_width, label_rect.getHeight(), TRUE);
S32 label_top = label_rect.mTop;
mLabel->reshapeToFitText(TRUE);

View File

@ -172,7 +172,7 @@ public:
virtual BOOL removeItem() = 0;
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
virtual BOOL isItemCopyable() const = 0;
virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0;
virtual BOOL copyToClipboard() const = 0;
virtual BOOL cutToClipboard() = 0;
virtual bool isCutToClipboard() { return false; };

View File

@ -3395,3 +3395,42 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien
}
return mIsFriendSignal->connect(cb);
}
bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str)
{
if (filter_str == "" || filter_str == " ")
{
clearHighlightedItems();
return false;
}
bool res = false;
setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red));
std::string filter_str_lc(filter_str);
LLStringUtil::toLower(filter_str_lc);
std::vector<LLScrollListItem*> data = getAllData();
std::vector<LLScrollListItem*>::iterator iter = data.begin();
while (iter != data.end())
{
LLScrollListCell* cell = (*iter)->getColumn(0);
if (cell)
{
std::string value = cell->getValue().asString();
LLStringUtil::toLower(value);
if (value.find(filter_str_lc) == std::string::npos)
{
(*iter)->setHighlighted(false);
}
else
{
(*iter)->setHighlighted(true);
res = true;
}
}
iter++;
}
return res;
}

View File

@ -419,6 +419,8 @@ public:
void setNeedsSort(bool val = true) { mSorted = !val; }
void dirtyColumns(); // some operation has potentially affected column layout or ordering
bool highlightMatchingItems(const std::string& filter_str);
boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
{
if (!mSortCallback) mSortCallback = new sort_signal_t();

View File

@ -101,7 +101,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
// Spin buttons
LLButton::Params up_button_params(p.up_button);
up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height);
up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
// Click callback starts within the button and ends within the button,
// but LLSpinCtrl handles the action continuosly so subsribers needs to
// be informed about click ending even if outside view, use 'up' instead
up_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
up_button_params.commit_on_capture_lost = true;
@ -110,7 +113,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
LLButton::Params down_button_params(p.down_button);
down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height);
down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
down_button_params.commit_on_capture_lost = true;
mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params);

View File

@ -355,95 +355,113 @@ void LLTextBase::onValueChange(S32 start, S32 end)
{
}
std::vector<LLRect> LLTextBase::getSelctionRects()
{
// Nor supposed to be called without selection
llassert(hasSelection());
llassert(!mLineInfoList.empty());
std::vector<LLRect> selection_rects;
S32 selection_left = llmin(mSelectionStart, mSelectionEnd);
S32 selection_right = llmax(mSelectionStart, mSelectionEnd);
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// binary search for line that starts before top of visible buffer
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
bool done = false;
// Find the coordinates of the selected area
for (; line_iter != end_iter && !done; ++line_iter)
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
// Use F32 otherwise a string of multiple segments
// will accumulate a large error
F32 left_precise = line_iter->mRect.mLeft;
F32 right_precise = line_iter->mRect.mLeft;
for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
F32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if (selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
left_precise += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
right_precise += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height);
right_precise += segment_width;
break;
}
}
LLRect selection_rect;
selection_rect.mLeft = left_precise;
selection_rect.mRight = right_precise;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
selection_rects.push_back(selection_rect);
}
}
return selection_rects;
}
// Draws the black box behind the selected text
void LLTextBase::drawSelectionBackground()
{
// Draw selection even if we don't have keyboard focus for search/replace
if( hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects;
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// binary search for line that starts before top of visible buffer
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
bool done = false;
// Find the coordinates of the selected area
for (;line_iter != end_iter && !done; ++line_iter)
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
LLRect selection_rect;
selection_rect.mLeft = line_iter->mRect.mLeft;
selection_rect.mRight = line_iter->mRect.mLeft;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
S32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if(selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mLeft += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
break;
}
}
selection_rects.push_back(selection_rect);
}
}
// Draw selection even if we don't have keyboard focus for search/replace
if (hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects = getSelctionRects();
// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mSelectedBGColor;
F32 alpha = hasFocus() ? 0.7f : 0.3f;
alpha *= getDrawContext().mAlpha;
LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha);
LLRect content_display_rect = getVisibleDocumentRect();
for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
rect_it != selection_rects.end();
@ -2551,7 +2569,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
}
S32 pos = getLength();
S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;
F32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;
segment_set_t::iterator line_seg_iter;
S32 line_seg_offset;
@ -2563,8 +2581,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
S32 segment_line_start = segmentp->getStart() + line_seg_offset;
S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd) - segment_line_start;
S32 text_width, text_height;
bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height);
F32 text_width;
S32 text_height;
bool newline = segmentp->getDimensionsF32(line_seg_offset, segment_line_length, text_width, text_height);
if(newline)
{
@ -2584,8 +2603,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
S32 offset;
if (!segmentp->canEdit())
{
S32 segment_width, segment_height;
segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
if (round && local_x - start_x > segment_width / 2)
{
offset = segment_line_length;
@ -2632,17 +2652,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
return LLRect();
}
LLRect doc_rect;
// clamp pos to valid values
pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1);
line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare());
doc_rect.mLeft = line_iter->mRect.mLeft;
doc_rect.mBottom = line_iter->mRect.mBottom;
doc_rect.mTop = line_iter->mRect.mTop;
segment_set_t::iterator line_seg_iter;
S32 line_seg_offset;
segment_set_t::iterator cursor_seg_iter;
@ -2650,6 +2664,8 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset);
getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset);
F32 doc_left_precise = line_iter->mRect.mLeft;
while(line_seg_iter != mSegments.end())
{
const LLTextSegmentPtr segmentp = *line_seg_iter;
@ -2657,18 +2673,20 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
if (line_seg_iter == cursor_seg_iter)
{
// cursor advanced to right based on difference in offset of cursor to start of line
S32 segment_width, segment_height;
segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
doc_rect.mLeft += segment_width;
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
doc_left_precise += segment_width;
break;
}
else
{
// add remainder of current text segment to cursor position
S32 segment_width, segment_height;
segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
doc_rect.mLeft += segment_width;
F32 segment_width;
S32 segment_height;
segmentp->getDimensionsF32(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
doc_left_precise += segment_width;
// offset will be 0 for all segments after the first
line_seg_offset = 0;
// go to next text segment on this line
@ -2676,6 +2694,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
}
}
LLRect doc_rect;
doc_rect.mLeft = doc_left_precise;
doc_rect.mBottom = line_iter->mRect.mBottom;
doc_rect.mTop = line_iter->mRect.mTop;
// set rect to 0 width
doc_rect.mRight = doc_rect.mLeft;

View File

@ -638,6 +638,8 @@ protected:
return mLabel.getString() + getToolTip();
}
std::vector<LLRect> getSelctionRects();
protected:
// text segmentation and flow
segment_set_t mSegments;

View File

@ -3067,18 +3067,54 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
{
LLMutexLock lock(&window_imp->mRawMouseMutex);
S32 speed;
const S32 DEFAULT_SPEED(10);
SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
if (speed == DEFAULT_SPEED)
bool absolute_coordinates = (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE);
if (absolute_coordinates)
{
window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
static S32 prev_absolute_x = 0;
static S32 prev_absolute_y = 0;
S32 absolute_x;
S32 absolute_y;
if ((raw->data.mouse.usFlags & 0x10) == 0x10) // touch screen? touch? Not defined in header
{
// touch screen spams (0,0) coordinates in a number of situations
// (0,0) might need to be filtered
absolute_x = raw->data.mouse.lLastX;
absolute_y = raw->data.mouse.lLastY;
}
else
{
bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP;
S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width;
absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height;
}
window_imp->mRawMouseDelta.mX += absolute_x - prev_absolute_x;
window_imp->mRawMouseDelta.mY -= absolute_y - prev_absolute_y;
prev_absolute_x = absolute_x;
prev_absolute_y = absolute_y;
}
else
{
window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
S32 speed;
const S32 DEFAULT_SPEED(10);
SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
if (speed == DEFAULT_SPEED)
{
window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
}
else
{
window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
}
}
}
}
@ -4215,7 +4251,10 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes)
if (needs_update)
{
mPreeditor->resetPreedit();
if (preedit_string.length() != 0 || result_string.length() != 0)
{
mPreeditor->resetPreedit();
}
if (result_string.length() > 0)
{

View File

@ -247,9 +247,9 @@ set(viewer_SOURCE_FILES
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
llfloateroutfitphotopreview.cpp
llfloateroutfitsnapshot.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
llfloatersimpleoutfitsnapshot.cpp
llfloaterpathfindingcharacters.cpp
llfloaterpathfindingconsole.cpp
llfloaterpathfindinglinksets.cpp
@ -889,9 +889,9 @@ set(viewer_HEADER_FILES
llfloaternotificationsconsole.h
llfloaternotificationstabbed.h
llfloateroutfitphotopreview.h
llfloateroutfitsnapshot.h
llfloaterobjectweights.h
llfloateropenobject.h
llfloatersimpleoutfitsnapshot.h
llfloaterpathfindingcharacters.h
llfloaterpathfindingconsole.h
llfloaterpathfindinglinksets.h

View File

@ -1 +1 @@
6.6.8
6.6.9

View File

@ -4747,7 +4747,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
<string>https://search.[GRID]/viewer/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>GuidebookURL</key>
<map>
@ -14634,6 +14634,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>MediaSoundsEarLocation</key>
<map>
<key>Comment</key>
<string>Location of the virtual ear for media and sounds</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>VoiceHost</key>
<map>
<key>Comment</key>

View File

@ -202,7 +202,7 @@ VARYING vec2 vary_texcoord2;
uniform float env_intensity;
uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
#ifdef HAS_ALPHA_MASK
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
uniform float minimum_alpha;
#endif
@ -227,12 +227,11 @@ void main()
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
diffcol.rgb *= vertex_color.rgb;
#ifdef HAS_ALPHA_MASK
#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND
if (diffcol.a*vertex_color.a < minimum_alpha)
#else
if (diffcol.a < minimum_alpha)
#endif
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
// Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
float bias = 0.001953125; // 1/512, or half an 8-bit quantization (SL-18637)
if (diffcol.a < minimum_alpha-bias)
{
discard;
}

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0
@ -80,7 +79,6 @@ RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
RenderAvatarMaxComplexity 1 25000
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
@ -111,7 +109,6 @@ RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
RenderAvatarMaxComplexity 1 35000
RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
@ -141,7 +138,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
@ -171,7 +167,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -201,7 +196,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -231,7 +225,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -261,7 +254,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -290,7 +282,6 @@ RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarVP 1 1
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -367,7 +358,6 @@ RenderCompressTextures 1 0
// No Pixel Shaders available
//
list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
@ -380,7 +370,6 @@ RenderShadowDetail 0 0
// No Vertex Shaders available
//
list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
@ -402,7 +391,6 @@ RenderVBOMappingDisable 1 1
list safe
RenderAnisotropic 1 0
RenderAvatarCloth 0 0
RenderAvatarVP 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
RenderObjectBump 0 0
@ -597,7 +585,6 @@ Disregard128DefaultDrawDistance 1 0
// on various ATI chipsets on drivers before 8.2
list ATIOldDriver
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
// Avoid driver crashes with some features on Linux with old ATI drivers
UseOcclusion 0 0

View File

@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarVP 1 1
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
RenderDelayVBUpdate 1 0

View File

@ -2912,9 +2912,11 @@ void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferr
bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure)
{
std::string url;
url = getRegion()->getCapability(capName);
if (!getRegion())
{
return false;
}
std::string url = getRegion()->getCapability(capName);
if (url.empty())
{

View File

@ -209,7 +209,7 @@
#include "llcommandlineparser.h"
#include "llfloatermemleak.h"
#include "llfloaterreg.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llfloatersnapshot.h"
#include "llsidepanelinventory.h"
#include "llatmosphere.h"
@ -1270,7 +1270,6 @@ bool LLAppViewer::init()
//LLSimpleton creations
LLEnvironment::createInstance();
LLEnvironment::getInstance()->initSingleton();
LLWorld::createInstance();
LLSelectMgr::createInstance();
LLViewerCamera::createInstance();
@ -1516,7 +1515,7 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
LLFloaterSimpleOutfitSnapshot::update();
gGLActive = FALSE;
}
}

View File

@ -102,7 +102,7 @@ LLVector3d LLAudioSourceVO::getPosGlobal() const
bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const
{
static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation", 0);
static LLCachedControl<S32> ear_mode(gSavedSettings, "MediaSoundsEarLocation", 0);
LLVector3d pos_ear;
@ -113,9 +113,6 @@ bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cu
break;
case 1: // avatar
case 2:
// voice support 'mixed' in '2' case with agent's position and camera's rotations
// but it is not defined in settings and uses camera as default
pos_ear = gAgent.getPositionGlobal();
break;

View File

@ -650,7 +650,7 @@ public:
void showInspector()
{
if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return;
if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) return;
if (mSourceType == CHAT_SOURCE_OBJECT)
{
@ -798,6 +798,7 @@ public:
icon->setValue(LLSD("OBJECT_Icon"));
break;
case CHAT_SOURCE_SYSTEM:
case CHAT_SOURCE_REGION:
icon->setValue(LLSD("SL_Logo"));
break;
case CHAT_SOURCE_TELEPORT:
@ -947,7 +948,7 @@ protected:
void showInfoCtrl()
{
const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType;
const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType;
if (isVisible)
{
const LLRect sticky_rect = mUserNameTextBox->getRect();
@ -1343,7 +1344,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params);
prependNewLineState = false;
}
else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION)
{
LLStyle::Params link_params(body_message_params);
link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));

View File

@ -87,7 +87,7 @@ public:
virtual BOOL removeItem() { return FALSE; }
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
virtual void move( LLFolderViewModelItem* parent_listener ) { }
virtual BOOL isItemCopyable() const { return FALSE; }
virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; }
virtual BOOL copyToClipboard() const { return FALSE; }
virtual BOOL cutToClipboard() { return FALSE; }
virtual BOOL isClipboardPasteable() const { return FALSE; }

View File

@ -41,6 +41,7 @@
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
#include "llstartup.h"
#include "lltextureentry.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
@ -79,11 +80,6 @@ static S32 bump_channel = -1;
#define LL_BUMPLIST_MULTITHREADED 0 // TODO -- figure out why this doesn't work
// static
void LLStandardBumpmap::init()
{
LLStandardBumpmap::restoreGL();
}
// static
void LLStandardBumpmap::shutdown()
@ -94,7 +90,7 @@ void LLStandardBumpmap::shutdown()
// static
void LLStandardBumpmap::restoreGL()
{
addstandard();
addstandard();
}
// static
@ -107,6 +103,12 @@ void LLStandardBumpmap::addstandard()
return ;
}
if (LLStartUp::getStartupState() < STATE_SEED_CAP_GRANTED)
{
// Not ready, need caps for images
return;
}
// can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps.
//llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 );
clear();
@ -769,8 +771,6 @@ void LLBumpImageList::init()
llassert( mBrightnessEntries.size() == 0 );
llassert( mDarknessEntries.size() == 0 );
LLStandardBumpmap::init();
LLStandardBumpmap::restoreGL();
sMainQueue = LL::WorkQueue::getInstance("mainloop");
sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.

View File

@ -118,7 +118,6 @@ public:
static void clear();
static void addstandard();
static void init();
static void shutdown();
static void restoreGL();
static void destroyGL();

View File

@ -874,26 +874,37 @@ void LLEnvironment::initSingleton()
requestRegion();
gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
if (!mParcelCallbackConnection.connected())
{
mParcelCallbackConnection = gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
//TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer.
// We need to know new env version to fix this, without it we can only do full re-request
// Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
//TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer.
// We need to know new env version to fix this, without it we can only do full re-request
// Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
mRegionUpdateCallbackConnection = LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
mRegionChangeCallbackConnection = gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
mPositionCallbackConnection = gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
}
if (!gGenericDispatcher.isHandlerPresent(MESSAGE_PUSHENVIRONMENT))
{
gGenericDispatcher.addHandler(MESSAGE_PUSHENVIRONMENT, &environment_push_dispatch_handler);
}
LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME);
LLEventPumps::instance().obtain(PUMP_EXPERIENCE).listen(LISTENER_NAME, [this](LLSD message) { listenExperiencePump(message); return false; });
}
void LLEnvironment::cleanupSingleton()
{
if (mParcelCallbackConnection.connected())
{
mParcelCallbackConnection.disconnect();
mRegionUpdateCallbackConnection.disconnect();
mRegionChangeCallbackConnection.disconnect();
mPositionCallbackConnection.disconnect();
}
LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME);
}

View File

@ -402,6 +402,11 @@ private:
bool mShowMoonBeacon;
S32 mEditorCounter;
connection_t mParcelCallbackConnection;
connection_t mRegionUpdateCallbackConnection;
connection_t mRegionChangeCallbackConnection;
connection_t mPositionCallbackConnection;
struct UpdateInfo
{
typedef std::shared_ptr<UpdateInfo> ptr_t;

View File

@ -84,7 +84,7 @@ LLFloater360Capture::~LLFloater360Capture()
// Tell the Simulator not to send us everything anymore
// and revert to the regular "keyhole" frustum of interest
// list updates.
if (gSavedSettings.getBOOL("360CaptureUseInterestListCap"))
if (!LLApp::isExiting() && gSavedSettings.getBOOL("360CaptureUseInterestListCap"))
{
const bool send_everything = false;
changeInterestListMode(send_everything);

View File

@ -307,7 +307,6 @@ void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
restoreFloater();
onCollapseToLine(this);
}
showTranslationCheckbox(LLTranslate::isTranslationConfigured());
}
// virtual

View File

@ -842,6 +842,7 @@ void LLFloaterIMSession::updateMessages()
std::string from = msg["from"].asString();
std::string message = msg["message"].asString();
bool is_history = msg["is_history"].asBoolean();
bool is_region_msg = msg["is_region_msg"].asBoolean();
LLChat chat;
chat.mFromID = from_id;
@ -849,6 +850,10 @@ void LLFloaterIMSession::updateMessages()
chat.mFromName = from;
chat.mTimeStr = time;
chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
if (is_region_msg)
{
chat.mSourceType = CHAT_SOURCE_REGION;
}
// process offer notification
if (msg.has("notification_id"))

View File

@ -253,7 +253,6 @@ BOOL LLFloaterIMSessionTab::postBuild()
mGearBtn = getChild<LLButton>("gear_btn");
mAddBtn = getChild<LLButton>("add_btn");
mVoiceButton = getChild<LLButton>("voice_call_btn");
mTranslationCheckBox = getChild<LLUICtrl>("translate_chat_checkbox_lp");
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder");
@ -811,8 +810,6 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat);
enableDisableCallBtn();
showTranslationCheckbox();
}
void LLFloaterIMSessionTab::forceReshape()
@ -829,11 +826,6 @@ void LLFloaterIMSessionTab::reshapeChatLayoutPanel()
mChatLayoutPanel->reshape(mChatLayoutPanel->getRect().getWidth(), mInputEditor->getRect().getHeight() + mInputEditorPad, FALSE);
}
void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
{
mTranslationCheckBox->setVisible(mIsNearbyChat && show);
}
// static
void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/)
{

View File

@ -71,8 +71,6 @@ public:
static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid);
static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid);
// show/hide the translation check box
void showTranslationCheckbox(const BOOL visible = FALSE);
bool isNearbyChat() {return mIsNearbyChat;}
@ -187,7 +185,6 @@ protected:
LLButton* mGearBtn;
LLButton* mAddBtn;
LLButton* mVoiceButton;
LLUICtrl* mTranslationCheckBox;
private:
// Handling selection and contextual menu

View File

@ -1,372 +0,0 @@
/**
* @file llfloateroutfitsnapshot.cpp
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2016, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatersnapshot.h"
#include "llfloateroutfitsnapshot.h"
#include "llagent.h"
#include "llfloaterreg.h"
#include "llimagefiltersmanager.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llpostcard.h"
#include "llresmgr.h" // LLLocale
#include "llsdserialize.h"
#include "llsidetraypanelcontainer.h"
#include "llspinctrl.h"
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot::Impl
///----------------------------------------------------------------------------
// virtual
LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found)
{
LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel);
if (!ok_if_not_found)
{
llassert_always(active_panel != NULL);
}
return active_panel;
}
// virtual
LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
}
// virtual
LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
}
// This is the main function that keeps all the GUI controls in sync with the saved settings.
// It should be called anytime a setting is changed that could affect the controls.
// No other methods should be changing any of the controls directly except for helpers called by this method.
// The basic pattern for programmatically changing the GUI settings is to first set the
// appropriate saved settings and then call this method to sync the GUI with them.
// FIXME: The above comment seems obsolete now.
// virtual
void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
{
LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater);
LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater);
LLSnapshotLivePreview* previewp = getPreviewView();
BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
// *TODO: Separate maximum size for Web images from postcards
LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
LLLocale locale(LLLocale::USER_LOCALE);
std::string bytes_string;
if (got_snap)
{
LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10);
}
// Update displayed image resolution.
LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text");
image_res_tb->setVisible(got_snap);
if (got_snap)
{
image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth()));
image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight()));
}
floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor"));
updateResolution(floater);
if (previewp)
{
previewp->setSnapshotType(shot_type);
previewp->setSnapshotFormat(shot_format);
previewp->setSnapshotBufferType(layer_type);
}
LLPanelSnapshot* current_panel = Impl::getActivePanel(floater);
if (current_panel)
{
LLSD info;
info["have-snapshot"] = got_snap;
current_panel->updateControls(info);
}
LL_DEBUGS() << "finished updating controls" << LL_ENDL;
}
// virtual
std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix()
{
return "panel_outfit_snapshot_";
}
// Show/hide upload status message.
// virtual
void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg)
{
mFloater->setSuccessLabelPanelVisible(finished && ok);
mFloater->setFailureLabelPanelVisible(finished && !ok);
if (finished)
{
LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
finished_lbl->setValue(result_text);
LLPanel* snapshot_panel = mFloater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
snapshot_panel->onOpen(LLSD());
}
}
void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data)
{
LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
if (!view)
{
llassert(view);
return;
}
S32 width = OUTFIT_SNAPSHOT_WIDTH;
S32 height = OUTFIT_SNAPSHOT_HEIGHT;
LLSnapshotLivePreview* previewp = getPreviewView();
if (previewp)
{
S32 original_width = 0, original_height = 0;
previewp->getSize(original_width, original_height);
if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
{ //clamp snapshot resolution to window size when showing UI or HUD in snapshot
width = llmin(width, gViewerWindow->getWindowWidthRaw());
height = llmin(height, gViewerWindow->getWindowHeightRaw());
}
llassert(width > 0 && height > 0);
// use the resolution from the selected pre-canned drop-down choice
LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
previewp->setSize(width, height);
if (original_width != width || original_height != height)
{
// hide old preview as the aspect ratio could be wrong
checkAutoSnapshot(previewp, FALSE);
LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
previewp->updateSnapshot(TRUE);
}
}
}
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot
///----------------------------------------------------------------------------
// Default constructor
LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key)
: LLFloaterSnapshotBase(key),
mOutfitGallery(NULL)
{
impl = new Impl(this);
}
LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot()
{
}
// virtual
BOOL LLFloaterOutfitSnapshot::postBuild()
{
mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this);
getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this);
getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this);
getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
// Filters
LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
for (U32 i = 0; i < filter_list.size(); i++)
{
filterbox->add(filter_list[i]);
}
childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
// create preview window
LLRect full_screen_rect = getRootView()->getRect();
LLSnapshotLivePreview::Params p;
p.rect(full_screen_rect);
LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
LLView* parent_view = gSnapshotFloaterView->getParent();
parent_view->removeChild(gSnapshotFloaterView);
// make sure preview is below snapshot floater
parent_view->addChild(previewp);
parent_view->addChild(gSnapshotFloaterView);
//move snapshot floater to special purpose snapshotfloaterview
gFloaterView->removeChild(this);
gSnapshotFloaterView->addChild(this);
impl->mPreviewHandle = previewp->getHandle();
previewp->setContainer(this);
impl->updateControls(this);
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
impl->updateLayout(this);
previewp->mKeepAspectRatio = FALSE;
previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
return TRUE;
}
// virtual
void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
{
LLSnapshotLivePreview* preview = getPreviewView();
if (preview)
{
LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
preview->updateSnapshot(TRUE);
}
focusFirstItem(FALSE);
gSnapshotFloaterView->setEnabled(TRUE);
gSnapshotFloaterView->setVisible(TRUE);
gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
impl->updateControls(this);
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
impl->updateLayout(this);
LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory");
snapshot_panel->onOpen(LLSD());
postPanelSwitch();
}
void LLFloaterOutfitSnapshot::onExtendFloater()
{
impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
}
// static
void LLFloaterOutfitSnapshot::update()
{
LLFloaterOutfitSnapshot* inst = findInstance();
if (inst != NULL)
{
inst->impl->updateLivePreview();
}
}
// static
LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance()
{
return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
}
// static
LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
}
// virtual
void LLFloaterOutfitSnapshot::saveTexture()
{
LL_DEBUGS() << "saveTexture" << LL_ENDL;
LLSnapshotLivePreview* previewp = getPreviewView();
if (!previewp)
{
llassert(previewp != NULL);
return;
}
if (mOutfitGallery)
{
mOutfitGallery->onBeforeOutfitSnapshotSave();
}
previewp->saveTexture(TRUE, getOutfitID().asString());
if (mOutfitGallery)
{
mOutfitGallery->onAfterOutfitSnapshotSave();
}
closeFloater();
}
///----------------------------------------------------------------------------
/// Class LLOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
{
}
LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView()
{
}

View File

@ -1,123 +0,0 @@
/**
* @file llfloateroutfitsnapshot.h
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2016, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATEROUTFITSNAPSHOT_H
#define LL_LLFLOATEROUTFITSNAPSHOT_H
#include "llfloater.h"
#include "llfloatersnapshot.h"
#include "lloutfitgallery.h"
#include "llsnapshotlivepreview.h"
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot
///----------------------------------------------------------------------------
class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase
{
LOG_CLASS(LLFloaterOutfitSnapshot);
public:
LLFloaterOutfitSnapshot(const LLSD& key);
/*virtual*/ ~LLFloaterOutfitSnapshot();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
static void update();
void onExtendFloater();
static LLFloaterOutfitSnapshot* getInstance();
static LLFloaterOutfitSnapshot* findInstance();
/*virtual*/ void saveTexture();
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
void setOutfitID(LLUUID id) { mOutfitID = id; }
LLUUID getOutfitID() { return mOutfitID; }
void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
class Impl;
friend class Impl;
private:
LLUUID mOutfitID;
LLOutfitGallery* mOutfitGallery;
};
///----------------------------------------------------------------------------
/// Class LLFloaterOutfitSnapshot::Impl
///----------------------------------------------------------------------------
class LLFloaterOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
{
LOG_CLASS(LLFloaterOutfitSnapshot::Impl);
public:
Impl(LLFloaterSnapshotBase* floater)
: LLFloaterSnapshotBase::ImplBase(floater)
{}
~Impl()
{}
void updateResolution(void* data);
static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
/*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
/*virtual*/ std::string getSnapshotPanelPrefix();
/*virtual*/ void updateControls(LLFloaterSnapshotBase* floater);
private:
/*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
/*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
};
///----------------------------------------------------------------------------
/// Class LLOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
class LLOutfitSnapshotFloaterView : public LLFloaterView
{
public:
struct Params
: public LLInitParam::Block<Params, LLFloaterView::Params>
{
};
protected:
LLOutfitSnapshotFloaterView(const Params& p);
friend class LLUICtrlFactory;
public:
virtual ~LLOutfitSnapshotFloaterView();
};
extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView;
#endif // LL_LLFLOATEROUTFITSNAPSHOT_H

View File

@ -512,6 +512,7 @@ void LLFloaterPreference::saveSettings()
if (panel)
panel->saveSettings();
}
saveIgnoredNotifications();
}
void LLFloaterPreference::apply()
@ -628,6 +629,8 @@ void LLFloaterPreference::cancel()
gSavedSettings.setString("PresetGraphicActive", mSavedGraphicsPreset);
LLPresetsManager::getInstance()->triggerChangeSignal();
}
restoreIgnoredNotifications();
}
void LLFloaterPreference::onOpen(const LLSD& key)
@ -1505,6 +1508,10 @@ void LLFloaterPreference::onClickEnablePopup()
}
buildPopupLists();
if (!mFilterEdit->getText().empty())
{
filterIgnorableNotifications();
}
}
void LLFloaterPreference::onClickDisablePopup()
@ -1520,6 +1527,10 @@ void LLFloaterPreference::onClickDisablePopup()
}
buildPopupLists();
if (!mFilterEdit->getText().empty())
{
filterIgnorableNotifications();
}
}
void LLFloaterPreference::resetAllIgnored()
@ -3545,11 +3556,24 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force)
return;
mSearchData->mRootTab->hightlightAndHide( seachValue );
filterIgnorableNotifications();
LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
if( pRoot )
pRoot->selectFirstTab();
}
void LLFloaterPreference::filterIgnorableNotifications()
{
bool visible = getChildRef<LLScrollListCtrl>("enabled_popups").highlightMatchingItems(mFilterEdit->getValue());
visible |= getChildRef<LLScrollListCtrl>("disabled_popups").highlightMatchingItems(mFilterEdit->getValue());
if (visible)
{
getChildRef<LLTabContainer>("pref core").setTabVisibility( getChild<LLPanel>("msgs"), true );
}
}
void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer )
{
if( !aView )
@ -3638,3 +3662,28 @@ void LLFloaterPreference::collectSearchableItems()
}
mSearchDataDirty = false;
}
void LLFloaterPreference::saveIgnoredNotifications()
{
for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
iter != LLNotifications::instance().templatesEnd();
++iter)
{
LLNotificationTemplatePtr templatep = iter->second;
LLNotificationFormPtr formp = templatep->mForm;
LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
if (ignore <= LLNotificationForm::IGNORE_NO)
continue;
mIgnorableNotifs[templatep->mName] = !formp->getIgnored();
}
}
void LLFloaterPreference::restoreIgnoredNotifications()
{
for (std::map<std::string, bool>::iterator it = mIgnorableNotifs.begin(); it != mIgnorableNotifs.end(); ++it)
{
LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(it->first, it->second);
}
}

View File

@ -143,6 +143,9 @@ public:
// cancel() can restore them.
void saveSettings();
void saveIgnoredNotifications();
void restoreIgnoredNotifications();
void setCacheLocation(const LLStringExplicit& location);
void onClickSetCache();
@ -223,6 +226,9 @@ private:
void onUpdateFilterTerm( bool force = false );
void collectSearchableItems();
void filterIgnorableNotifications();
std::map<std::string, bool> mIgnorableNotifs;
};
class LLPanelPreference : public LLPanel

View File

@ -0,0 +1,333 @@
/**
* @file llfloatersimpleoutfitsnapshot.cpp
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llfloaterreg.h"
#include "llimagefiltersmanager.h"
#include "llstatusbar.h" // can_afford_transaction()
#include "llnotificationsutil.h"
#include "llagentbenefits.h"
#include "llviewercontrol.h"
LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView = NULL;
const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
static LLDefaultChildRegistry::Register<LLSimpleOutfitSnapshotFloaterView> r("simple_snapshot_outfit_floater_view");
///----------------------------------------------------------------------------
/// Class LLFloaterSimpleOutfitSnapshot::Impl
///----------------------------------------------------------------------------
LLSnapshotModel::ESnapshotFormat LLFloaterSimpleOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
}
LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
{
return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
}
void LLFloaterSimpleOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
{
LLSnapshotLivePreview* previewp = getPreviewView();
updateResolution(floater);
if (previewp)
{
previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE);
previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG);
previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR);
}
}
std::string LLFloaterSimpleOutfitSnapshot::Impl::getSnapshotPanelPrefix()
{
return "panel_outfit_snapshot_";
}
void LLFloaterSimpleOutfitSnapshot::Impl::updateResolution(void* data)
{
LLFloaterSimpleOutfitSnapshot *view = (LLFloaterSimpleOutfitSnapshot *)data;
if (!view)
{
llassert(view);
return;
}
S32 width = OUTFIT_SNAPSHOT_WIDTH;
S32 height = OUTFIT_SNAPSHOT_HEIGHT;
LLSnapshotLivePreview* previewp = getPreviewView();
if (previewp)
{
S32 original_width = 0, original_height = 0;
previewp->getSize(original_width, original_height);
if (gSavedSettings.getBOOL("RenderHUDInSnapshot"))
{ //clamp snapshot resolution to window size when showing UI HUD in snapshot
width = llmin(width, gViewerWindow->getWindowWidthRaw());
height = llmin(height, gViewerWindow->getWindowHeightRaw());
}
llassert(width > 0 && height > 0);
previewp->setSize(width, height);
if (original_width != width || original_height != height)
{
// hide old preview as the aspect ratio could be wrong
checkAutoSnapshot(previewp, FALSE);
previewp->updateSnapshot(TRUE);
}
}
}
void LLFloaterSimpleOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg)
{
switch (status)
{
case STATUS_READY:
mFloater->setCtrlsEnabled(true);
break;
case STATUS_WORKING:
mFloater->setCtrlsEnabled(false);
break;
case STATUS_FINISHED:
mFloater->setCtrlsEnabled(true);
break;
}
mStatus = status;
}
///----------------------------------------------------------------re------------
/// Class LLFloaterSimpleOutfitSnapshot
///----------------------------------------------------------------------------
LLFloaterSimpleOutfitSnapshot::LLFloaterSimpleOutfitSnapshot(const LLSD& key)
: LLFloaterSnapshotBase(key),
mOutfitGallery(NULL)
{
impl = new Impl(this);
}
LLFloaterSimpleOutfitSnapshot::~LLFloaterSimpleOutfitSnapshot()
{
}
BOOL LLFloaterSimpleOutfitSnapshot::postBuild()
{
getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
childSetAction("save_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onSend, this));
childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onCancel, this));
mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
// create preview window
LLRect full_screen_rect = getRootView()->getRect();
LLSnapshotLivePreview::Params p;
p.rect(full_screen_rect);
LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
LLView* parent_view = gSnapshotFloaterView->getParent();
parent_view->removeChild(gSnapshotFloaterView);
// make sure preview is below snapshot floater
parent_view->addChild(previewp);
parent_view->addChild(gSnapshotFloaterView);
//move snapshot floater to special purpose snapshotfloaterview
gFloaterView->removeChild(this);
gSnapshotFloaterView->addChild(this);
impl->mPreviewHandle = previewp->getHandle();
previewp->setContainer(this);
impl->updateControls(this);
impl->setAdvanced(true);
impl->setSkipReshaping(true);
previewp->mKeepAspectRatio = FALSE;
previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
previewp->setAllowRenderUI(false);
return TRUE;
}
const S32 PREVIEW_OFFSET_X = 12;
const S32 PREVIEW_OFFSET_Y = 70;
void LLFloaterSimpleOutfitSnapshot::draw()
{
LLSnapshotLivePreview* previewp = getPreviewView();
if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
{
// don't render snapshot window in snapshot, even if "show ui" is turned on
return;
}
LLFloater::draw();
if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible())
{
if(previewp->getThumbnailImage())
{
bool working = impl->getStatus() == ImplBase::STATUS_WORKING;
const LLRect& thumbnail_rect = getThumbnailPlaceholderRect();
const S32 thumbnail_w = previewp->getThumbnailWidth();
const S32 thumbnail_h = previewp->getThumbnailHeight();
S32 offset_x = PREVIEW_OFFSET_X;
S32 offset_y = PREVIEW_OFFSET_Y;
gGL.matrixMode(LLRender::MM_MODELVIEW);
// Apply floater transparency to the texture unless the floater is focused.
F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
LLColor4 color = working ? LLColor4::grey4 : LLColor4::white;
gl_draw_scaled_image(offset_x, offset_y,
thumbnail_w, thumbnail_h,
previewp->getThumbnailImage(), color % alpha);
#if LL_DARWIN
std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "OutfitSnapshotMacMask" : "OutfitSnapshotMacMask2";
#else
std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "FloaterFocusBackgroundColor" : "DkGray";
#endif
previewp->drawPreviewRect(offset_x, offset_y, LLUIColorTable::instance().getColor(alpha_color));
gGL.pushUIMatrix();
LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom);
mThumbnailPlaceholder->draw();
gGL.popUIMatrix();
}
}
impl->updateLayout(this);
}
void LLFloaterSimpleOutfitSnapshot::onOpen(const LLSD& key)
{
LLSnapshotLivePreview* preview = getPreviewView();
if (preview)
{
preview->updateSnapshot(TRUE);
}
focusFirstItem(FALSE);
gSnapshotFloaterView->setEnabled(TRUE);
gSnapshotFloaterView->setVisible(TRUE);
gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
impl->updateControls(this);
impl->setStatus(ImplBase::STATUS_READY);
}
void LLFloaterSimpleOutfitSnapshot::onCancel()
{
closeFloater();
}
void LLFloaterSimpleOutfitSnapshot::onSend()
{
S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
if (can_afford_transaction(expected_upload_cost))
{
saveTexture();
postSave();
}
else
{
LLSD args;
args["COST"] = llformat("%d", expected_upload_cost);
LLNotificationsUtil::add("ErrorPhotoCannotAfford", args);
inventorySaveFailed();
}
}
void LLFloaterSimpleOutfitSnapshot::postSave()
{
impl->setStatus(ImplBase::STATUS_WORKING);
}
// static
void LLFloaterSimpleOutfitSnapshot::update()
{
LLFloaterSimpleOutfitSnapshot* inst = findInstance();
if (inst != NULL)
{
inst->impl->updateLivePreview();
}
}
// static
LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::findInstance()
{
return LLFloaterReg::findTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
}
// static
LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
}
void LLFloaterSimpleOutfitSnapshot::saveTexture()
{
LLSnapshotLivePreview* previewp = getPreviewView();
if (!previewp)
{
llassert(previewp != NULL);
return;
}
if (mOutfitGallery)
{
mOutfitGallery->onBeforeOutfitSnapshotSave();
}
previewp->saveTexture(TRUE, getOutfitID().asString());
if (mOutfitGallery)
{
mOutfitGallery->onAfterOutfitSnapshotSave();
}
closeFloater();
}
///----------------------------------------------------------------------------
/// Class LLSimpleOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
LLSimpleOutfitSnapshotFloaterView::LLSimpleOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
{
}
LLSimpleOutfitSnapshotFloaterView::~LLSimpleOutfitSnapshotFloaterView()
{
}

View File

@ -0,0 +1,129 @@
/**
* @file llfloatersimpleoutfitsnapshot.h
* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
#define LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
#include "llfloater.h"
#include "llfloatersnapshot.h"
#include "lloutfitgallery.h"
#include "llsnapshotlivepreview.h"
///----------------------------------------------------------------------------
/// Class LLFloaterSimpleOutfitSnapshot
///----------------------------------------------------------------------------
class LLFloaterSimpleOutfitSnapshot : public LLFloaterSnapshotBase
{
LOG_CLASS(LLFloaterSimpleOutfitSnapshot);
public:
LLFloaterSimpleOutfitSnapshot(const LLSD& key);
~LLFloaterSimpleOutfitSnapshot();
BOOL postBuild();
void onOpen(const LLSD& key);
void draw();
static void update();
static LLFloaterSimpleOutfitSnapshot* getInstance();
static LLFloaterSimpleOutfitSnapshot* findInstance();
void saveTexture();
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
void setOutfitID(LLUUID id) { mOutfitID = id; }
LLUUID getOutfitID() { return mOutfitID; }
void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
void postSave();
class Impl;
friend class Impl;
private:
void onSend();
void onCancel();
LLUUID mOutfitID;
LLOutfitGallery* mOutfitGallery;
};
///----------------------------------------------------------------------------
/// Class LLFloaterSimpleOutfitSnapshot::Impl
///----------------------------------------------------------------------------
class LLFloaterSimpleOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
{
LOG_CLASS(LLFloaterSimpleOutfitSnapshot::Impl);
public:
Impl(LLFloaterSnapshotBase* floater)
: LLFloaterSnapshotBase::ImplBase(floater)
{}
~Impl()
{}
void updateResolution(void* data);
static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) { return NULL; }
LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
std::string getSnapshotPanelPrefix();
void updateControls(LLFloaterSnapshotBase* floater);
void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
private:
LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) {};
};
///----------------------------------------------------------------------------
/// Class LLSimpleOutfitSnapshotFloaterView
///----------------------------------------------------------------------------
class LLSimpleOutfitSnapshotFloaterView : public LLFloaterView
{
public:
struct Params
: public LLInitParam::Block<Params, LLFloaterView::Params>
{
};
protected:
LLSimpleOutfitSnapshotFloaterView(const Params& p);
friend class LLUICtrlFactory;
public:
virtual ~LLSimpleOutfitSnapshotFloaterView();
};
extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView;
#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H

View File

@ -176,16 +176,20 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate
LLUICtrl* thumbnail_placeholder = floaterp->getChild<LLUICtrl>("thumbnail_placeholder");
thumbnail_placeholder->setVisible(mAdvanced);
thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(mAdvanced);
floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(mAdvanced);
if (floaterp->hasChild("360_label", TRUE))
{
floaterp->getChild<LLUICtrl>("360_label")->setVisible(mAdvanced);
}
if(!floaterp->isMinimized())
if (!mSkipReshaping)
{
floaterp->reshape(floater_width, floaterp->getRect().getHeight());
thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
if (!floaterp->isMinimized())
{
floaterp->reshape(floater_width, floaterp->getRect().getHeight());
}
}
bool use_freeze_frame = floaterp->getChild<LLUICtrl>("freeze_frame_check")->getValue().asBoolean();
@ -1193,7 +1197,7 @@ S32 LLFloaterSnapshotBase::notify(const LLSD& info)
// The refresh button is initially hidden. We show it after the first update,
// i.e. when preview appears.
if (!mRefreshBtn->getVisible())
if (mRefreshBtn && !mRefreshBtn->getVisible())
{
mRefreshBtn->setVisible(true);
}

View File

@ -59,9 +59,9 @@ public:
const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); }
void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); }
void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); }
void setRefreshLabelVisible(bool value) { if (mRefreshLabel) mRefreshLabel->setVisible(value); }
void setSuccessLabelPanelVisible(bool value) { if (mSucceessLblPanel) mSucceessLblPanel->setVisible(value); }
void setFailureLabelPanelVisible(bool value) { if (mFailureLblPanel) mFailureLblPanel->setVisible(value); }
void inventorySaveFailed();
class ImplBase;
@ -88,6 +88,7 @@ public:
mLastToolset(NULL),
mAspectRatioCheckOff(false),
mNeedRefresh(false),
mSkipReshaping(false),
mStatus(STATUS_READY),
mFloater(floater)
{}
@ -120,6 +121,7 @@ public:
static BOOL updatePreviewList(bool initialized);
void setAdvanced(bool advanced) { mAdvanced = advanced; }
void setSkipReshaping(bool skip) { mSkipReshaping = skip; }
virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0;
virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
@ -135,6 +137,7 @@ public:
bool mAspectRatioCheckOff;
bool mNeedRefresh;
bool mAdvanced;
bool mSkipReshaping;
EStatus mStatus;
};

View File

@ -289,7 +289,6 @@ void LLFloaterTranslationSettings::onBtnOK()
gSavedSettings.setString("TranslationService", getSelectedService());
gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
showTranslationCheckbox(LLTranslate::isTranslationConfigured());
closeFloater(false);
}

View File

@ -175,8 +175,7 @@ public:
virtual void processGroupData() = 0;
protected:
LLUUID mGroupId;
private:
bool mRequestProcessed;
bool mRequestProcessed;
};
class LLFetchLeaveGroupData: public LLFetchGroupMemberData
@ -189,6 +188,22 @@ public:
{
LLGroupActions::processLeaveGroupDataResponse(mGroupId);
}
void changed(LLGroupChange gc)
{
if (gc == GC_PROPERTIES && !mRequestProcessed)
{
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId);
if (!gdatap)
{
LL_WARNS() << "GroupData was NULL" << LL_ENDL;
}
else
{
processGroupData();
mRequestProcessed = true;
}
}
}
};
LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;

View File

@ -55,6 +55,7 @@
#include "llviewerwindow.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
#include "llworld.h"
#include "boost/lexical_cast.hpp"
#if LL_MSVC
@ -520,8 +521,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
dialog,
parent_estate_id,
region_id,
position,
true);
position);
if (!gIMMgr->isDNDMessageSend(session_id))
{
@ -572,6 +572,15 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
}
if (!mute_im)
{
bool region_message = false;
if (region_id.isNull())
{
LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(from_id);
if (regionp)
{
region_message = true;
}
}
gIMMgr->addMessage(
session_id,
from_id,
@ -583,7 +592,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
parent_estate_id,
region_id,
position,
true);
region_message);
}
else
{
@ -1102,8 +1111,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
IM_SESSION_INVITE,
parent_estate_id,
region_id,
position,
true);
position);
}
else
{
@ -1128,8 +1136,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
IM_SESSION_INVITE,
parent_estate_id,
region_id,
position,
true);
position);
}
break;

View File

@ -760,7 +760,7 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_
}
}
void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history)
void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history, bool is_region_msg)
{
LLSD message;
message["from"] = from;
@ -769,6 +769,7 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f
message["time"] = time;
message["index"] = (LLSD::Integer)mMsgs.size();
message["is_history"] = is_history;
message["is_region_msg"] = is_region_msg;
LL_DEBUGS("UIUsage") << "addMessage " << " from " << from << " from_id " << from_id << " utf8_text " << utf8_text << " time " << time << " is_history " << is_history << " session mType " << mType << LL_ENDL;
if (from_id == gAgent.getID())
@ -1149,7 +1150,7 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id)
mNoUnreadMsgsSignal(arg);
}
bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) {
bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg) {
LLIMSession* session = findIMSession(session_id);
@ -1159,7 +1160,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
return false;
}
session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false)); //might want to add date separately
session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false), false, is_region_msg); //might want to add date separately
return true;
}
@ -1197,9 +1198,9 @@ bool LLIMModel::proccessOnlineOfflineNotification(
}
bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
const std::string& utf8_text, bool log2file /* = true */) {
const std::string& utf8_text, bool log2file, bool is_region_msg) {
LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file);
LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg);
if (!session) return false;
//good place to add some1 to recent list
@ -1224,7 +1225,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
}
LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
const std::string& utf8_text, bool log2file /* = true */)
const std::string& utf8_text, bool log2file, bool is_region_msg)
{
LLIMSession* session = findIMSession(session_id);
@ -1240,7 +1241,7 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id,
from_name = SYSTEM_FROM;
}
addToHistory(session_id, from_name, from_id, utf8_text);
addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg);
if (log2file)
{
logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text);
@ -2663,7 +2664,7 @@ void LLIMMgr::addMessage(
U32 parent_estate_id,
const LLUUID& region_id,
const LLVector3& position,
bool link_name) // If this is true, then we insert the name and link it to a profile
bool is_region_msg)
{
LLUUID other_participant_id = target_id;
@ -2735,7 +2736,7 @@ void LLIMMgr::addMessage(
//<< "*** region_id: " << region_id << std::endl
//<< "*** position: " << position << std::endl;
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str());
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str(), true, is_region_msg);
}
// Logically it would make more sense to reject the session sooner, in another area of the
@ -2765,7 +2766,7 @@ void LLIMMgr::addMessage(
if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message)
{
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg);
}
// Open conversation floater if offline messages are present
@ -3692,8 +3693,7 @@ public:
IM_SESSION_INVITE,
message_params["parent_estate_id"].asInteger(),
message_params["region_id"].asUUID(),
ll_vector3_from_sd(message_params["position"]),
true);
ll_vector3_from_sd(message_params["position"]));
if (LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat))
{

View File

@ -81,7 +81,7 @@ public:
void sessionInitReplyReceived(const LLUUID& new_session_id);
void addMessagesFromHistory(const std::list<LLSD>& history);
void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false);
void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false);
void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
/** @deprecated */
@ -208,13 +208,13 @@ public:
* and also saved into a file if log2file is specified.
* It sends new message signal for each added message.
*/
bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true);
bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false);
/**
* Similar to addMessage(...) above but won't send a signal about a new message added
*/
LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
const std::string& utf8_text, bool log2file = true);
const std::string& utf8_text, bool log2file = true, bool is_region_msg = false);
/**
* Add a system message to an IM Model
@ -292,7 +292,7 @@ private:
/**
* Add message to a list of message associated with session specified by session_id
*/
bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false);
};
@ -334,7 +334,7 @@ public:
U32 parent_estate_id = 0,
const LLUUID& region_id = LLUUID::null,
const LLVector3& position = LLVector3::zero,
bool link_name = false);
bool is_region_msg = false);
void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args);

View File

@ -614,7 +614,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
if (cat)
{
LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, item_id);
if (!cat_br.isItemCopyable())
if (!cat_br.isItemCopyable(false))
return FALSE;
// Skip to the next item in the clipboard
continue;
@ -622,7 +622,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
// Each item must be copyable to be pastable
LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id);
if (!item_br.isItemCopyable())
if (!item_br.isItemCopyable(false))
{
return FALSE;
}
@ -654,6 +654,11 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
{
return FALSE;
}
if (gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID()))
{
return FALSE;
}
}
const LLViewerInventoryCategory *cat = model->getCategory(objects.at(i));
if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
@ -729,15 +734,15 @@ void hide_context_entries(LLMenuGL& menu,
}
bool found = false;
menuentry_vec_t::const_iterator itor2;
for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2)
{
if (*itor2 == name)
{
found = true;
break;
}
}
std::string myinput;
std::vector<std::string> mylist{ "a", "b", "c" };
menuentry_vec_t::const_iterator itor2 = std::find(entries_to_show.begin(), entries_to_show.end(), name);
if (itor2 != entries_to_show.end())
{
found = true;
}
// Don't allow multiple separators in a row (e.g. such as if there are no items
// between two separators).
@ -755,7 +760,21 @@ void hide_context_entries(LLMenuGL& menu,
menu_item->setVisible(FALSE);
}
menu_item->setEnabled(FALSE);
if (menu_item->getEnabled())
{
// These should stay enabled unless specifically disabled
const menuentry_vec_t exceptions = {
"Detach From Yourself",
"Wearable And Object Wear",
"Wearable Add",
};
menuentry_vec_t::const_iterator itor2 = std::find(exceptions.begin(), exceptions.end(), name);
if (itor2 == exceptions.end())
{
menu_item->setEnabled(FALSE);
}
}
}
else
{
@ -882,7 +901,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Paste"));
}
if (gSavedSettings.getBOOL("InventoryLinking"))
static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
if (inventory_linking)
{
items.push_back(std::string("Paste As Link"));
if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0)
@ -2059,7 +2079,8 @@ BOOL LLItemBridge::removeItem()
// we can't do this check because we may have items in a folder somewhere that is
// not yet in memory, so we don't want false negatives. (If disabled, then we
// know we only have links in the Outfits folder which we explicitly fetch.)
if (!gSavedSettings.getBOOL("InventoryLinking"))
static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
if (!inventory_linking)
{
if (!item->getIsLinkType())
{
@ -2102,22 +2123,24 @@ BOOL LLItemBridge::confirmRemoveItem(const LLSD& notification, const LLSD& respo
return FALSE;
}
BOOL LLItemBridge::isItemCopyable() const
bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const
{
LLViewerInventoryItem* item = getItem();
if (item)
{
// Can't copy worn objects.
// Worn objects are tied to their inworld conterparts
// Copy of modified worn object will return object with obsolete asset and inventory
if(get_is_item_worn(mUUID))
{
return FALSE;
}
LLViewerInventoryItem* item = getItem();
if (!item)
{
return false;
}
// Can't copy worn objects.
// Worn objects are tied to their inworld conterparts
// Copy of modified worn object will return object with obsolete asset and inventory
if (get_is_item_worn(mUUID))
{
return false;
}
return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking");
}
return FALSE;
static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
return (can_copy_as_link && inventory_linking)
|| item->getPermissions().allowCopyBy(gAgent.getID());
}
LLViewerInventoryItem* LLItemBridge::getItem() const
@ -2321,7 +2344,7 @@ BOOL LLFolderBridge::isUpToDate() const
return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN;
}
BOOL LLFolderBridge::isItemCopyable() const
bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const
{
// Folders are copyable if items in them are, recursively, copyable.
@ -2336,22 +2359,26 @@ BOOL LLFolderBridge::isItemCopyable() const
{
LLInventoryItem* item = *iter;
LLItemBridge item_br(mInventoryPanel.get(), mRoot, item->getUUID());
if (!item_br.isItemCopyable())
return FALSE;
}
if (!item_br.isItemCopyable(false))
{
return false;
}
}
// Check the folders
LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
{
{
LLViewerInventoryCategory* category = *iter;
LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, category->getUUID());
if (!cat_br.isItemCopyable())
return FALSE;
}
return TRUE;
}
if (!cat_br.isItemCopyable(false))
{
return false;
}
}
return true;
}
BOOL LLFolderBridge::isClipboardPasteable() const
{
@ -3768,6 +3795,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
LLInventoryObject *obj = model->getObject(item_id);
if (obj)
{
if (move_is_into_lost_and_found)
{
if (LLAssetType::AT_CATEGORY == obj->getType())
@ -4296,7 +4324,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
items.push_back(std::string("IM All Contacts In Folder"));
}
if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren())
if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren() && (type != LLFolderType::FT_OUTFIT))
{
items.push_back(std::string("Ungroup folder items"));
}

View File

@ -119,7 +119,7 @@ public:
//virtual BOOL removeItem() = 0;
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
virtual BOOL isItemCopyable() const { return FALSE; }
virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; }
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard();
virtual bool isCutToClipboard();
@ -245,7 +245,7 @@ public:
virtual BOOL isItemRenameable() const;
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL removeItem();
virtual BOOL isItemCopyable() const;
virtual bool isItemCopyable(bool can_copy_as_link = true) const;
virtual bool hasChildren() const { return FALSE; }
virtual BOOL isUpToDate() const { return TRUE; }
virtual LLUIImagePtr getIconOverlay() const;
@ -318,7 +318,7 @@ public:
virtual BOOL isItemRemovable() const;
virtual BOOL isItemMovable() const ;
virtual BOOL isUpToDate() const;
virtual BOOL isItemCopyable() const;
virtual bool isItemCopyable(bool can_copy_as_link = true) const;
virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;

View File

@ -862,6 +862,9 @@ LLUUID create_folder_for_item(LLInventoryItem* item, const LLUUID& destFolderId)
S32 depth_nesting_in_marketplace(LLUUID cur_uuid)
{
// Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none
// Todo: findCategoryUUIDForType is somewhat expensive with large
// flat root folders yet we use depth_nesting_in_marketplace at
// every turn, find a way to correctly cache this id.
const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
if (marketplace_listings_uuid.isNull())
{
@ -1504,7 +1507,12 @@ void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level)
// This function does no deletion of listings but a mere audit and raises issues to the user (through the
// optional callback cb). It also returns a boolean, true if things validate, false if issues are raised.
// The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders.
bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth)
bool validate_marketplacelistings(
LLInventoryCategory* cat,
validation_callback_t cb,
bool fix_hierarchy,
S32 depth,
bool notify_observers)
{
#if 0
// Used only for debug
@ -1570,7 +1578,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName());
LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid);
gInventory.changeCategoryParent(viewer_cat, folder_uuid, false);
result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1);
result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1, notify_observers);
return result;
}
else
@ -1740,7 +1748,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
// Next type
update_marketplace_category(parent_uuid);
update_marketplace_category(folder_uuid);
gInventory.notifyObservers();
if (notify_observers)
{
gInventory.notifyObservers();
}
items_vector_it++;
}
}
@ -1754,7 +1765,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
{
LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (*iter);
gInventory.changeCategoryParent(viewer_cat, parent_uuid, false);
result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth);
result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth, false);
}
}
}
@ -1826,7 +1837,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
cb(message,depth,LLError::LEVEL_WARN);
}
gInventory.removeCategory(cat->getUUID());
gInventory.notifyObservers();
if (notify_observers)
{
gInventory.notifyObservers();
}
return result && !has_bad_items;
}
}
@ -1840,11 +1854,14 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
{
LLInventoryCategory* category = *iter;
result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1);
result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1, false);
}
update_marketplace_category(cat->getUUID(), true, true);
gInventory.notifyObservers();
if (notify_observers)
{
gInventory.notifyObservers();
}
return result && !has_bad_items;
}
@ -2583,8 +2600,62 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
}
std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs();
// copy list of applicable items into a vector for bulk handling
uuid_vec_t ids;
std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
if (action == "wear" || action == "wear_add")
{
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
std::copy_if(selected_uuid_set.begin(),
selected_uuid_set.end(),
std::back_inserter(ids),
[trash_id, mp_id](LLUUID id)
{
if (get_is_item_worn(id)
|| LLAppearanceMgr::instance().getIsInCOF(id)
|| gInventory.isObjectDescendentOf(id, trash_id))
{
return false;
}
if (mp_id.notNull() && gInventory.isObjectDescendentOf(id, mp_id))
{
return false;
}
LLInventoryObject* obj = (LLInventoryObject*)gInventory.getObject(id);
if (!obj)
{
return false;
}
if (obj->getIsLinkType() && gInventory.isObjectDescendentOf(obj->getLinkedUUID(), trash_id))
{
return false;
}
if (obj->getIsLinkType() && LLAssetType::lookupIsLinkType(obj->getType()))
{
// missing
return false;
}
return true;
}
);
}
else if (isRemoveAction(action))
{
std::copy_if(selected_uuid_set.begin(),
selected_uuid_set.end(),
std::back_inserter(ids),
[](LLUUID id)
{
return get_is_item_worn(id);
}
);
}
else
{
std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
}
// Check for actions that get handled in bulk
if (action == "wear")
{

View File

@ -87,7 +87,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve
bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size = 1, bool check_items = true, bool from_paste = false);
bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false);
bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false, bool move_no_copy_items = false);
bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1);
bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1, bool notify_observers = true);
S32 depth_nesting_in_marketplace(LLUUID cur_uuid);
LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);

View File

@ -1851,9 +1851,13 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
mChangedItemIDs.insert(referent);
}
// Fix me: From DD-81, probably shouldn't be here, instead
// should be somewhere in an observer
update_marketplace_category(referent, false);
if (mask != LLInventoryObserver::LABEL)
{
// Fix me: From DD-81, probably shouldn't be here, instead
// should be somewhere in an observer or in
// LLMarketplaceInventoryObserver::onIdleProcessQueue
update_marketplace_category(referent, false);
}
if (mask & LLInventoryObserver::ADD)
{

View File

@ -30,6 +30,7 @@
#include "llagent.h"
#include "llbufferstream.h"
#include "llcallbacklist.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llnotificationsutil.h"
@ -605,20 +606,67 @@ public:
LLMarketplaceInventoryObserver() {}
virtual ~LLMarketplaceInventoryObserver() {}
virtual void changed(U32 mask);
private:
static void onIdleProcessQueue(void *userdata);
// doesn't hold just marketplace related ids
static std::set<LLUUID> sAddQueue;
static std::set<LLUUID> sStructureQueue;
static bool sProcessingQueue;
};
std::set<LLUUID> LLMarketplaceInventoryObserver::sAddQueue;
std::set<LLUUID> LLMarketplaceInventoryObserver::sStructureQueue;
bool LLMarketplaceInventoryObserver::sProcessingQueue = false;
void LLMarketplaceInventoryObserver::changed(U32 mask)
{
// When things are added to the marketplace, we might need to re-validate and fix the containing listings
if (mask & LLInventoryObserver::ADD)
if (mask & LLInventoryObserver::ADD && LLMarketplaceData::instance().hasValidationWaiting())
{
// When things are added to the marketplace, we might need to re-validate and fix the containing listings
// just add whole list even if it contains items and non-marketplace folders
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
std::set<LLUUID>::const_iterator id_it = changed_items.begin();
std::set<LLUUID>::const_iterator id_end = changed_items.end();
sAddQueue.insert(changed_items.begin(), changed_items.end());
}
if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE))
{
// When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder:
// * stock counts changing : no copy items coming in and out will change the stock count on folders
// * version and listing folders : moving those might invalidate the marketplace data itself
// Since we should cannot raise inventory change while the observer is called (the list will be cleared
// once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied.
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
sStructureQueue.insert(changed_items.begin(), changed_items.end());
}
if (!sProcessingQueue && (!sAddQueue.empty() || !sStructureQueue.empty()))
{
gIdleCallbacks.addFunction(onIdleProcessQueue, NULL);
// can do without sProcessingQueue, but it's usufull for simplicity and reliability
sProcessingQueue = true;
}
}
void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)
{
U64 start_time = LLTimer::getTotalTime(); // microseconds
const U64 MAX_PROCESSING_TIME = 1000;
U64 stop_time = start_time + MAX_PROCESSING_TIME;
if (!sAddQueue.empty())
{
// Make a copy of sAddQueue since decrementValidationWaiting
// can theoretically add more items
std::set<LLUUID> add_queue(sAddQueue);
sAddQueue.clear();
std::set<LLUUID>::const_iterator id_it = add_queue.begin();
std::set<LLUUID>::const_iterator id_end = add_queue.end();
// First, count the number of items in this list...
S32 count = 0;
for (;id_it != id_end; ++id_it)
for (; id_it != id_end; ++id_it)
{
LLInventoryObject* obj = gInventory.getObject(*id_it);
if (obj && (LLAssetType::AT_CATEGORY != obj->getType()))
@ -629,56 +677,58 @@ void LLMarketplaceInventoryObserver::changed(U32 mask)
// Then, decrement the folders of that amount
// Note that of all of those, only one folder will be a listing folder (if at all).
// The other will be ignored by the decrement method.
id_it = changed_items.begin();
for (;id_it != id_end; ++id_it)
id_it = add_queue.begin();
for (; id_it != id_end; ++id_it)
{
LLInventoryObject* obj = gInventory.getObject(*id_it);
if (obj && (LLAssetType::AT_CATEGORY == obj->getType()))
{
LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(),count);
// can trigger notifyObservers
LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(), count);
}
}
}
// When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder:
// * stock counts changing : no copy items coming in and out will change the stock count on folders
// * version and listing folders : moving those might invalidate the marketplace data itself
// Since we should cannot raise inventory change while the observer is called (the list will be cleared
// once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied.
if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE))
{
const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
std::set<LLUUID>::const_iterator id_it = changed_items.begin();
std::set<LLUUID>::const_iterator id_end = changed_items.end();
for (;id_it != id_end; ++id_it)
}
while (!sStructureQueue.empty() && LLTimer::getTotalTime() < stop_time)
{
std::set<LLUUID>::const_iterator id_it = sStructureQueue.begin();
LLInventoryObject* obj = gInventory.getObject(*id_it);
if (obj)
{
LLInventoryObject* obj = gInventory.getObject(*id_it);
if (obj)
if (LLAssetType::AT_CATEGORY == obj->getType())
{
if (LLAssetType::AT_CATEGORY == obj->getType())
// If it's a folder known to the marketplace, let's check it's in proper shape
if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it))
{
// If it's a folder known to the marketplace, let's check it's in proper shape
if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it))
{
LLInventoryCategory* cat = (LLInventoryCategory*)(obj);
validate_marketplacelistings(cat);
}
LLInventoryCategory* cat = (LLInventoryCategory*)(obj);
// can trigger notifyObservers
// can cause more structural changes
validate_marketplacelistings(cat);
}
else
}
else
{
// If it's not a category, it's an item...
LLInventoryItem* item = (LLInventoryItem*)(obj);
// If it's a no copy item, we may need to update the label count of marketplace listings
if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
{
// If it's not a category, it's an item...
LLInventoryItem* item = (LLInventoryItem*)(obj);
// If it's a no copy item, we may need to update the label count of marketplace listings
if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
{
LLMarketplaceData::instance().setDirtyCount();
}
LLMarketplaceData::instance().setDirtyCount();
}
}
}
}
// sStructureQueue could have been modified in validate_marketplacelistings
// adding items does not invalidate existing iterator
sStructureQueue.erase(id_it);
}
if (LLApp::isExiting() || (sAddQueue.empty() && sStructureQueue.empty()))
{
// Nothing to do anymore
gIdleCallbacks.deleteFunction(onIdleProcessQueue, NULL);
sProcessingQueue = false;
}
}
// Tuple == Item

View File

@ -242,6 +242,7 @@ public:
void setUpdating(const LLUUID& folder_id, bool isUpdating);
// Used to decide when to run a validation on listing folders
bool hasValidationWaiting() { return mValidationWaitingList.size() > 0; }
void setValidationWaiting(const LLUUID& folder_id, S32 count);
void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1);

View File

@ -41,7 +41,7 @@
#include "llfilepicker.h"
#include "llfloaterperms.h"
#include "llfloaterreg.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llimagedimensionsinfo.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
@ -1386,8 +1386,8 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id)
{
LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot");
LLFloaterOutfitSnapshot* snapshot_floater = LLFloaterOutfitSnapshot::getInstance();
LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot");
LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance();
if (snapshot_floater)
{
snapshot_floater->setOutfitID(selected_outfit_id);

View File

@ -454,7 +454,8 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_
LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID());
if(media_impl)
{
media_impl->navigateHome();
media_impl->setPriority(LLPluginClassMedia::PRIORITY_NORMAL);
media_impl->navigateHome();
return true;
}
}

View File

@ -93,6 +93,8 @@ enum {
MI_HOLE_COUNT
};
const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters
//static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright");
BOOL LLPanelObject::postBuild()
@ -1685,6 +1687,16 @@ void LLPanelObject::sendPosition(BOOL btn_down)
mCtrlPosZ->set(LLWorld::getInstance()->resolveLandHeightAgent(newpos) + 1.f);
}
}
else
{
if (newpos.length() > MAX_ATTACHMENT_DIST)
{
newpos.clampLength(MAX_ATTACHMENT_DIST);
mCtrlPosX->set(newpos.mV[VX]);
mCtrlPosY->set(newpos.mV[VY]);
mCtrlPosZ->set(newpos.mV[VZ]);
}
}
// Make sure new position is in a valid region, so the object
// won't get dumped by the simulator.
@ -2191,6 +2203,10 @@ void LLPanelObject::onPastePos()
mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width);
//height will get properly clamped by sendPosition
}
else
{
mClipboardPos.clampLength(MAX_ATTACHMENT_DIST);
}
mCtrlPosX->set( mClipboardPos.mV[VX] );
mCtrlPosY->set( mClipboardPos.mV[VY] );

View File

@ -131,7 +131,7 @@ public:
virtual BOOL removeItem();
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
virtual void move(LLFolderViewModelItem* parent_listener);
virtual BOOL isItemCopyable() const;
virtual bool isItemCopyable(bool can_copy_as_link = true) const;
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard();
virtual BOOL isClipboardPasteable() const;
@ -439,10 +439,10 @@ void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)
{
}
BOOL LLTaskInvFVBridge::isItemCopyable() const
bool LLTaskInvFVBridge::isItemCopyable(bool can_link) const
{
LLInventoryItem* item = findItem();
if(!item) return FALSE;
if(!item) return false;
return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
GP_OBJECT_MANIPULATE);
}

View File

@ -127,7 +127,10 @@ void LLPanelPresetsCameraPulldown::onRowClick(const LLSD& user_data)
LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL;
LLFloaterCamera::switchToPreset(name);
setVisible(FALSE);
// Scroll grabbed focus, drop it to prevent selection of parent menu
setFocus(FALSE);
setVisible(FALSE);
}
else
{

View File

@ -122,6 +122,9 @@ void LLPanelPresetsPulldown::onRowClick(const LLSD& user_data)
LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL;
LLPresetsManager::getInstance()->loadPreset(PRESETS_GRAPHIC, name);
// Scroll grabbed focus, drop it to prevent selection of parent menu
setFocus(FALSE);
setVisible(FALSE);
}
else

View File

@ -51,6 +51,7 @@ void LLPanelPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
/*virtual*/
void LLPanelPulldown::onTopLost()
{
setFocus(FALSE); // drop focus to prevent transfer to parent
setVisible(FALSE);
}
@ -113,6 +114,7 @@ void LLPanelPulldown::draw()
if (alpha == 0.f)
{
setFocus(FALSE); // drop focus to prevent transfer to parent
setVisible(FALSE);
}
}

View File

@ -187,82 +187,8 @@ void LLScriptEditor::drawSelectionBackground()
// Draw selection even if we don't have keyboard focus for search/replace
if( hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects;
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// binary search for line that starts before top of visible buffer
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, LLTextBase::compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, LLTextBase::compare_top());
bool done = false;
// Find the coordinates of the selected area
for (;line_iter != end_iter && !done; ++line_iter)
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
LLRect selection_rect;
selection_rect.mLeft = line_iter->mRect.mLeft;
selection_rect.mRight = line_iter->mRect.mLeft;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
S32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if(selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mLeft += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
break;
}
}
selection_rects.push_back(selection_rect);
}
}
std::vector<LLRect> selection_rects = getSelctionRects();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor;
F32 alpha = hasFocus() ? 0.7f : 0.3f;
@ -272,6 +198,7 @@ void LLScriptEditor::drawSelectionBackground()
(1.f + color.mV[VGREEN]) * 0.5f,
(1.f + color.mV[VBLUE]) * 0.5f,
alpha);
LLRect content_display_rect = getVisibleDocumentRect();
for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
rect_it != selection_rects.end();

View File

@ -39,7 +39,6 @@
class LLViewerCamera;
class LLVOWLSky;
class LLVOWLClouds;
class LLSky

View File

@ -233,7 +233,7 @@ bool LLSnapshotLivePreview::setSnapshotQuality(S32 quality, bool set_by_user)
return false;
}
void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color)
{
F32 line_width ;
glGetFloatv(GL_LINE_WIDTH, &line_width) ;
@ -246,7 +246,6 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
//draw four alpha rectangles to cover areas outside of the snapshot image
if(!mKeepAspectRatio)
{
LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ;
S32 dwl = 0, dwr = 0 ;
if(mThumbnailWidth > mPreviewRect.getWidth())
{

View File

@ -112,7 +112,7 @@ public:
BOOL setThumbnailImageSize() ;
void generateThumbnailImage(BOOL force_update = FALSE) ;
void resetThumbnailImage() { mThumbnailImage = NULL ; }
void drawPreviewRect(S32 offset_x, S32 offset_y) ;
void drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color = LLColor4(0.5f, 0.5f, 0.5f, 0.8f));
void prepareFreezeFrame();
LLViewerTexture* getBigThumbnailImage();

View File

@ -1285,9 +1285,6 @@ bool idle_startup()
// Initialize classes w/graphics stuff.
//
LLViewerStatsRecorder::instance(); // Since textures work in threads
gTextureList.doPrefetchImages();
display_startup();
LLSurface::initClasses();
display_startup();
@ -1432,6 +1429,15 @@ bool idle_startup()
if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
{
display_startup();
// These textures are not warrantied to be cached, so needs
// to hapen with caps granted
gTextureList.doPrefetchImages();
// will init images, should be done with caps, but before gSky.init()
LLEnvironment::getInstance()->initSingleton();
display_startup();
update_texture_fetch();
display_startup();
@ -2526,8 +2532,6 @@ void use_circuit_callback(void**, S32 result)
void register_viewer_callbacks(LLMessageSystem* msg)
{
msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data );
msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader );
msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket );
msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update );
msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update );
msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update );
@ -2913,6 +2917,7 @@ void reset_login()
gAgentWearables.cleanup();
gAgentCamera.cleanup();
gAgent.cleanup();
gSky.cleanup(); // mVOSkyp is an inworld object.
LLWorld::getInstance()->resetClass();
if ( gViewerWindow )

View File

@ -714,7 +714,7 @@ BOOL LLSurfacePatch::updateTexture()
{
mVObjp->dirtyGeom();
gPipeline.markGLRebuild(mVObjp);
return TRUE;
return !mSTexUpdate;
}
}
}

View File

@ -1646,6 +1646,12 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
{
gDirUtilp->deleteFilesInDir(dirname, mask);
}
#if LL_WINDOWS
// Texture cache can be large and can take a while to remove
// assure OS that processes is alive and not hanging
MSG msg;
PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD);
#endif
}
gDirUtilp->deleteFilesInDir(mTexturesDirName, mask); // headers, fast cache
if (purge_directories)

View File

@ -282,7 +282,6 @@ static const char* e_state_name[] =
"LOAD_FROM_TEXTURE_CACHE",
"CACHE_POST",
"LOAD_FROM_NETWORK",
"LOAD_FROM_SIMULATOR",
"WAIT_HTTP_RESOURCE",
"WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
@ -456,7 +455,6 @@ public:
LOAD_FROM_TEXTURE_CACHE,
CACHE_POST,
LOAD_FROM_NETWORK,
LOAD_FROM_SIMULATOR,
WAIT_HTTP_RESOURCE, // Waiting for HTTP resources
WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources
SEND_HTTP_REQ, // Commit to sending as HTTP
@ -497,8 +495,6 @@ private:
// Locks: Mw
void clearPackets();
// Locks: Mw
void setupPacketData();
// Locks: Mw (ctor invokes without lock)
U32 calcWorkPriority();
@ -506,10 +502,6 @@ private:
// Locks: Mw
void removeFromCache();
// Threads: Ttf
// Locks: Mw
bool processSimulatorPackets();
// Threads: Ttf
bool writeToCacheComplete();
@ -612,8 +604,7 @@ private:
BOOL mHaveAllData;
BOOL mInLocalCache;
BOOL mInCache;
bool mCanUseHTTP,
mCanUseNET ; //can get from asset server.
bool mCanUseHTTP;
S32 mRetryAttempt;
S32 mActiveCount;
LLCore::HttpStatus mGetStatus;
@ -885,7 +876,6 @@ const char* sStateDescs[] = {
"LOAD_FROM_TEXTURE_CACHE",
"CACHE_POST",
"LOAD_FROM_NETWORK",
"LOAD_FROM_SIMULATOR",
"WAIT_HTTP_RESOURCE",
"WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
@ -897,7 +887,7 @@ const char* sStateDescs[] = {
"DONE"
};
const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR,
const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK,
LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE };
// static
@ -972,8 +962,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mResourceWaitCount(0U),
mFetchRetryPolicy(10.0,3600.0,2.0,10)
{
mCanUseNET = mUrl.empty() ;
calcWorkPriority();
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
@ -1037,39 +1025,6 @@ void LLTextureFetchWorker::clearPackets()
mFirstPacket = 0;
}
// Locks: Mw
void LLTextureFetchWorker::setupPacketData()
{
S32 data_size = 0;
if (mFormattedImage.notNull())
{
data_size = mFormattedImage->getDataSize();
}
if (data_size > 0)
{
// Only used for simulator requests
mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1;
if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size)
{
LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL;
removeFromCache();
resetFormattedData();
clearPackets();
}
else if (mFileSize > 0)
{
mLastPacket = mFirstPacket-1;
mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1;
}
else
{
// This file was cached using HTTP so we have to refetch the first packet
resetFormattedData();
clearPackets();
}
}
}
// Locks: Mw (ctor invokes without lock)
U32 LLTextureFetchWorker::calcWorkPriority()
{
@ -1177,13 +1132,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
if(mImagePriority < F_ALMOST_ZERO)
{
if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
if (mState == INIT || mState == LOAD_FROM_NETWORK)
{
LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
return true; // abort
}
}
if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
if(mState > CACHE_POST && !mCanUseHTTP)
{
//nowhere to get data, abort.
LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL;
@ -1387,10 +1342,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
LLViewerRegion* region = NULL;
if (mHost.isInvalid())
region = gAgent.getRegion();
else
region = LLWorld::getInstance()->getRegion(mHost);
if (mHost.isInvalid())
{
region = gAgent.getRegion();
}
else if (LLWorld::instanceExists())
{
region = LLWorld::getInstance()->getRegion(mHost);
}
if (region)
{
@ -1408,14 +1367,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
else
{
mCanUseHTTP = false ;
LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
}
}
else
{
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
mCanUseHTTP = false;
}
}
@ -1434,84 +1393,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
// don't return, fall through to next state
}
else if (mSentRequest == UNSENT && mCanUseNET)
{
// Add this to the network queue and sit here.
// LLTextureFetch::update() will send off a request which will change our state
mWriteToCacheState = CAN_WRITE ;
mRequestedSize = mDesiredSize;
mRequestedDiscard = mDesiredDiscard;
mSentRequest = QUEUED;
mFetcher->addToNetworkQueue(this);
recordTextureStart(false);
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;
}
else
{
// Shouldn't need to do anything here
//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
// Make certain this is in the network queue
//mFetcher->addToNetworkQueue(this);
//recordTextureStart(false);
//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;
}
}
if (mState == LOAD_FROM_SIMULATOR)
{
if (mFormattedImage.isNull())
{
mFormattedImage = new LLImageJ2C;
}
if (processSimulatorPackets())
{
// Capture some measure of total size for metrics
F64 byte_count = 0;
if (mLastPacket >= mFirstPacket)
{
for (S32 i=mFirstPacket; i<=mLastPacket; i++)
{
llassert_always((i>=0) && (i<mPackets.size()));
if (mPackets[i])
{
byte_count += mPackets[i]->mSize;
}
}
}
LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL;
mFetcher->removeFromNetworkQueue(this, false);
if (mFormattedImage.isNull() || !mFormattedImage->getDataSize())
{
// processSimulatorPackets() failed
// LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL;
LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL;
return true; // failed
}
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if (mLoadedDiscard < 0)
{
LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
<< ", should be >=0" << LL_ENDL;
}
setState(DECODE_IMAGE);
mWriteToCacheState = SHOULD_WRITE;
recordTextureDone(false, byte_count);
}
else
{
mFetcher->addToNetworkQueue(this); // failsafe
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
recordTextureStart(false);
}
return false;
}
if (mState == WAIT_HTTP_RESOURCE)
{
// NOTE:
@ -1553,8 +1440,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL;
return true; // abort
}
mFetcher->removeFromNetworkQueue(this, false);
S32 cur_size = 0;
if (mFormattedImage.notNull())
@ -1701,17 +1586,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return true;
}
// roll back to try UDP
if (mCanUseNET)
{
setState(INIT);
mCanUseHTTP = false;
mUrl.clear();
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
releaseHttpSemaphore();
return false;
}
}
else if (http_service_unavail == mGetStatus)
{
@ -2280,69 +2154,6 @@ void LLTextureFetchWorker::removeFromCache()
}
//////////////////////////////////////////////////////////////////////////////
// Threads: Ttf
// Locks: Mw
bool LLTextureFetchWorker::processSimulatorPackets()
{
if (mFormattedImage.isNull() || mRequestedSize < 0)
{
// not sure how we got here, but not a valid state, abort!
llassert_always(mDecodeHandle == 0);
mFormattedImage = NULL;
return true;
}
if (mLastPacket >= mFirstPacket)
{
S32 buffer_size = mFormattedImage->getDataSize();
for (S32 i = mFirstPacket; i<=mLastPacket; i++)
{
llassert_always((i>=0) && (i<mPackets.size()));
llassert_always(mPackets[i]);
buffer_size += mPackets[i]->mSize;
}
bool have_all_data = mLastPacket >= mTotalPackets-1;
if (mRequestedSize <= 0)
{
// We received a packed but haven't requested anything yet (edge case)
// Return true (we're "done") since we didn't request anything
return true;
}
if (buffer_size >= mRequestedSize || have_all_data)
{
/// We have enough (or all) data
if (have_all_data)
{
mHaveAllData = TRUE;
}
S32 cur_size = mFormattedImage->getDataSize();
if (buffer_size > cur_size)
{
/// We have new data
U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size);
S32 offset = 0;
if (cur_size > 0 && mFirstPacket > 0)
{
memcpy(buffer, mFormattedImage->getData(), cur_size);
offset = cur_size;
}
for (S32 i=mFirstPacket; i<=mLastPacket; i++)
{
memcpy(buffer + offset, mPackets[i]->mData, mPackets[i]->mSize);
offset += mPackets[i]->mSize;
}
// NOTE: setData releases current data
mFormattedImage->setData(buffer, buffer_size);
}
mLoadedDiscard = mRequestedDiscard;
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
// Threads: Ttf
@ -2813,40 +2624,6 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
}
// Threads: T* (but Ttf in practice)
// protected
void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
{
lockQueue(); // +Mfq
bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ;
unlockQueue(); // -Mfq
LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
if (in_request_map)
{
// only add to the queue if in the request map
// i.e. a delete has not been requested
mNetworkQueue.insert(worker->mID);
}
for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
iter1 != mCancelQueue.end(); ++iter1)
{
iter1->second.erase(worker->mID);
}
} // -Mfnq
// Threads: T*
void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel)
{
LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
size_t erased = mNetworkQueue.erase(worker->mID);
if (cancel && erased > 0)
{
mCancelQueue[worker->mHost].insert(worker->mID);
}
} // -Mfnq
// Threads: T*
//
// protected
@ -2880,7 +2657,6 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
worker->scheduleDelete();
@ -2908,7 +2684,6 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
worker->scheduleDelete();
@ -3197,17 +2972,6 @@ S32 LLTextureFetch::update(F32 max_time_ms)
S32 res = LLWorkerThread::update(max_time_ms);
if (!mDebugPause)
{
// this is the startup state when send_complete_agent_movement() message is sent.
// Before this, the RequestImages message sent by sendRequestListToSimulators
// won't work so don't bother trying
if (LLStartUp::getStartupState() > STATE_AGENT_SEND)
{
sendRequestListToSimulators();
}
}
if (!mThreaded)
{
commonUpdate();
@ -3298,202 +3062,6 @@ void LLTextureFetch::threadedUpdate()
//////////////////////////////////////////////////////////////////////////////
// Threads: Tmain
void LLTextureFetch::sendRequestListToSimulators()
{
// All requests
const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps
// Sim requests
const S32 IMAGES_PER_REQUEST = 50;
const F32 SIM_LAZY_FLUSH_TIMEOUT = 10.0f; // temp
const F32 MIN_REQUEST_TIME = 1.0f;
const F32 MIN_DELTA_PRIORITY = 1000.f;
// Periodically, gather the list of textures that need data from the network
// And send the requests out to the simulators
static LLFrameTimer timer;
if (timer.getElapsedTimeF32() < REQUEST_DELTA_TIME)
{
return;
}
timer.reset();
// Send requests
typedef std::set<LLTextureFetchWorker*,LLTextureFetchWorker::Compare> request_list_t;
typedef std::map< LLHost, request_list_t > work_request_map_t;
work_request_map_t requests;
{
LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
{
queue_t::iterator curiter = iter++;
LLTextureFetchWorker* req = getWorker(*curiter);
if (!req)
{
mNetworkQueue.erase(curiter);
continue; // paranoia
}
if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) &&
(req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR))
{
// We already received our URL, remove from the queue
LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL;
mNetworkQueue.erase(curiter);
continue;
}
if (req->mID == mDebugID)
{
mDebugCount++; // for setting breakpoints
}
if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM &&
req->mTotalPackets > 0 &&
req->mLastPacket >= req->mTotalPackets-1)
{
// We have all the packets... make sure this is high priority
// req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
continue;
}
F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32();
{
F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
(delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
(elapsed >= SIM_LAZY_FLUSH_TIMEOUT))
{
requests[req->mHost].insert(req);
}
}
}
} // -Mfnq
for (work_request_map_t::iterator iter1 = requests.begin();
iter1 != requests.end(); ++iter1)
{
LLHost host = iter1->first;
// invalid host = use agent host
if (host.isInvalid())
{
host = gAgent.getRegionHost();
}
S32 sim_request_count = 0;
for (request_list_t::iterator iter2 = iter1->second.begin();
iter2 != iter1->second.end(); ++iter2)
{
LLTextureFetchWorker* req = *iter2;
if (gMessageSystem)
{
if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM)
{
// Initialize packet data based on data read from cache
req->lockWorkMutex(); // +Mw
req->setupPacketData();
req->unlockWorkMutex(); // -Mw
}
if (0 == sim_request_count)
{
gMessageSystem->newMessageFast(_PREHASH_RequestImage);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
S32 packet = req->mLastPacket + 1;
gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard);
gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority);
gMessageSystem->addU32Fast(_PREHASH_Packet, packet);
gMessageSystem->addU8Fast(_PREHASH_Type, req->mType);
// LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
// << " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL;
static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
if (log_to_viewer_log || log_to_sim)
{
mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime());
mTextureInfo.setRequestOffset(req->mID, 0);
mTextureInfo.setRequestSize(req->mID, 0);
mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP);
}
req->lockWorkMutex(); // +Mw
req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
req->mSimRequestedDiscard = req->mDesiredDiscard;
req->mRequestedPriority = req->mImagePriority;
req->mRequestedDeltaTimer.reset();
req->unlockWorkMutex(); // -Mw
sim_request_count++;
if (sim_request_count >= IMAGES_PER_REQUEST)
{
// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
gMessageSystem->sendSemiReliable(host, NULL, NULL);
sim_request_count = 0;
}
}
}
if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST)
{
// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
gMessageSystem->sendSemiReliable(host, NULL, NULL);
sim_request_count = 0;
}
}
// Send cancelations
{
LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
if (gMessageSystem && !mCancelQueue.empty())
{
for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
iter1 != mCancelQueue.end(); ++iter1)
{
LLHost host = iter1->first;
if (host.isInvalid())
{
host = gAgent.getRegionHost();
}
S32 request_count = 0;
for (queue_t::iterator iter2 = iter1->second.begin();
iter2 != iter1->second.end(); ++iter2)
{
if (0 == request_count)
{
gMessageSystem->newMessageFast(_PREHASH_RequestImage);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
}
gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2);
gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1);
gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0);
gMessageSystem->addU32Fast(_PREHASH_Packet, 0);
gMessageSystem->addU8Fast(_PREHASH_Type, 0);
// LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL;
request_count++;
if (request_count >= IMAGES_PER_REQUEST)
{
gMessageSystem->sendSemiReliable(host, NULL, NULL);
request_count = 0;
}
}
if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
{
gMessageSystem->sendSemiReliable(host, NULL, NULL);
}
}
mCancelQueue.clear();
}
} // -Mfnq
}
//////////////////////////////////////////////////////////////////////////////
// Threads: T*
// Locks: Mw
bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
@ -3556,138 +3124,6 @@ void LLTextureFetchWorker::setState(e_state new_state)
mState = new_state;
}
// Threads: T*
bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
U16 data_size, U8* data)
{
LLTextureFetchWorker* worker = getWorker(id);
bool res = true;
++mPacketCount;
if (!worker)
{
// LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL;
res = false;
}
else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK ||
worker->mSentRequest != LLTextureFetchWorker::SENT_SIM)
{
// LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id
// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState]
// << " sent: " << worker->mSentRequest << LL_ENDL;
res = false;
}
else if (worker->mLastPacket != -1)
{
// check to see if we've gotten this packet before
// LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL;
res = false;
}
else if (!data_size)
{
// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
res = false;
}
if (!res)
{
mNetworkQueueMutex.lock(); // +Mfnq
++mBadPacketCount;
mCancelQueue[host].insert(id);
mNetworkQueueMutex.unlock(); // -Mfnq
return false;
}
LLViewerStatsRecorder::instance().textureFetch(data_size);
LLViewerStatsRecorder::instance().log(0.1f);
worker->lockWorkMutex();
// Copy header data into image object
worker->mImageCodec = codec;
worker->mTotalPackets = packets;
worker->mFileSize = (S32)totalbytes;
llassert_always(totalbytes > 0);
llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
res = worker->insertPacket(0, data, data_size);
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
worker->unlockWorkMutex(); // -Mw
return res;
}
// Threads: T*
bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
{
LLTextureFetchWorker* worker = getWorker(id);
bool res = true;
++mPacketCount;
if (!worker)
{
// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL;
res = false;
}
else if (worker->mLastPacket == -1)
{
// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL;
res = false;
}
else if (!data_size)
{
// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
res = false;
}
if (!res)
{
mNetworkQueueMutex.lock(); // +Mfnq
++mBadPacketCount;
mCancelQueue[host].insert(id);
mNetworkQueueMutex.unlock(); // -Mfnq
return false;
}
LLViewerStatsRecorder::instance().textureFetch(data_size);
LLViewerStatsRecorder::instance().log(0.1f);
worker->lockWorkMutex();
res = worker->insertPacket(packet_num, data, data_size);
if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) ||
(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
{
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
}
else
{
// LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id
// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL;
removeFromNetworkQueue(worker, true); // failsafe
}
if (packet_num >= (worker->mTotalPackets - 1))
{
static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
if (log_to_viewer_log || log_to_sim)
{
U64Microseconds timeNow = LLTimer::getTotalTime();
mTextureInfoMainThread.setRequestSize(id, worker->mFileSize);
mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow);
}
}
worker->unlockWorkMutex(); // -Mw
return res;
}
//////////////////////////////////////////////////////////////////////////////
// Threads: T*
@ -3726,13 +3162,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32();
if (worker->mFileSize > 0)
{
if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR)
{
S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE;
data_size = llmax(data_size, 0);
data_progress = (F32)data_size / (F32)worker->mFileSize;
}
else if (worker->mFormattedImage.notNull())
if (worker->mFormattedImage.notNull())
{
data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize;
}

View File

@ -101,12 +101,6 @@ public:
// Threads: T*
bool updateRequestPriority(const LLUUID& id, F32 priority);
// Threads: T*
bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
// Threads: T*
bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
// Threads: T* (but not safe)
void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
@ -227,12 +221,6 @@ public:
// ----------------------------------
protected:
// Threads: T* (but Ttf in practice)
void addToNetworkQueue(LLTextureFetchWorker* worker);
// Threads: T*
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
// Threads: T*
void addToHTTPQueue(const LLUUID& id);
@ -251,9 +239,6 @@ protected:
bool runCondition();
private:
// Threads: Tmain
void sendRequestListToSimulators();
// Threads: Ttf
/*virtual*/ void startThread(void);
@ -319,7 +304,7 @@ public:
private:
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue
LLTextureCache* mTextureCache;
LLImageDecodeThread* mImageDecodeThread;
@ -330,10 +315,8 @@ private:
// Set of requests that require network data
typedef std::set<LLUUID> queue_t;
queue_t mNetworkQueue; // Mfnq
queue_t mHTTPTextureQueue; // Mfnq
typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
cancel_queue_t mCancelQueue; // Mfnq
F32 mTextureBandwidth; // <none>
F32 mMaxBandwidth; // Mfnq
LLTextureInfo mTextureInfo;

View File

@ -234,7 +234,6 @@ void LLTextureBar::draw()
{ "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE
{ "DSK", LLColor4::blue }, // CACHE_POST
{ "NET", LLColor4::green }, // LOAD_FROM_NETWORK
{ "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2
{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ

View File

@ -44,6 +44,7 @@
#include "llagent.h" // HACK for destinations guide on startup
#include "llfloaterreg.h" // HACK for destinations guide on startup
#include "llviewercontrol.h" // HACK for destinations guide on startup
#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX
#include <boost/foreach.hpp>
@ -319,6 +320,22 @@ bool LLToolBarView::loadToolbars(bool force_default)
}
}
}
// SL-18581: Don't show the starter avatar toolbar button for NUX users
LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
if (gAgent.isFirstLogin()
&& my_outfits_cat != NULL
&& my_outfits_cat->getDescendentCount() > 0)
{
for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
if (mToolbars[i])
{
mToolbars[i]->removeCommand(LLCommandId("avatar"));
}
}
}
mToolbarsLoaded = true;
return true;
}

View File

@ -868,11 +868,6 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
{
floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
}
LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
{
floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
}
}
//=========================================================================
@ -951,11 +946,5 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
}
}
LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
{
floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
}
}

View File

@ -496,7 +496,20 @@ void audio_update_listener()
if (gAudiop)
{
// update listener position because agent has moved
LLVector3d lpos_global = gAgentCamera.getCameraPositionGlobal();
static LLUICachedControl<S32> mEarLocation("MediaSoundsEarLocation", 0);
LLVector3d ear_position;
switch(mEarLocation)
{
case 0:
default:
ear_position = gAgentCamera.getCameraPositionGlobal();
break;
case 1:
ear_position = gAgent.getPositionGlobal();
break;
}
LLVector3d lpos_global = ear_position;
LLVector3 lpos_global_f;
lpos_global_f.setVec(lpos_global);

View File

@ -616,7 +616,7 @@ bool toggle_show_navigation_panel(const LLSD& newvalue)
LLNavigationBar::getInstance()->setVisible(value);
gSavedSettings.setBOOL("ShowMiniLocationPanel", !value);
gViewerWindow->reshapeStatusBarContainer();
return true;
}

View File

@ -103,7 +103,7 @@
#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
#include "llfloateroutfitphotopreview.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llfloaterpathfindingcharacters.h"
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindinglinksets.h"
@ -170,6 +170,7 @@
// *NOTE: Please add files in alphabetical order to keep merges easy.
// handle secondlife:///app/openfloater/{NAME} URLs
const std::string FLOATER_PROFILE("profile");
class LLFloaterOpenHandler : public LLCommandHandler
{
public:
@ -185,7 +186,12 @@ public:
}
const std::string floater_name = LLURI::unescape(params[0].asString());
LLFloaterReg::showInstance(floater_name);
LLSD key;
if (floater_name == FLOATER_PROFILE)
{
key["id"] = gAgentID;
}
LLFloaterReg::showInstance(floater_name, key);
return true;
}
@ -368,7 +374,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
LLFloaterReg::add("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleOutfitSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);

View File

@ -45,7 +45,7 @@
#include "llglheaders.h"
extern LLPipeline gPipeline;
const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters?
const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters
//-----------------------------------------------------------------------------
// LLViewerJointAttachment()

View File

@ -3581,7 +3581,20 @@ void LLViewerMediaImpl::calculateInterest()
LLVector3d global_delta = agent_global - obj_global ;
mProximityDistance = global_delta.magVecSquared(); // use distance-squared because it's cheaper and sorts the same.
LLVector3d camera_delta = gAgentCamera.getCameraPositionGlobal() - obj_global;
static LLUICachedControl<S32> mEarLocation("MediaSoundsEarLocation", 0);
LLVector3d ear_position;
switch(mEarLocation)
{
case 0:
default:
ear_position = gAgentCamera.getCameraPositionGlobal();
break;
case 1:
ear_position = agent_global;
break;
}
LLVector3d camera_delta = ear_position - obj_global;
mProximityCamera = camera_delta.magVec();
}
}

View File

@ -4334,6 +4334,10 @@ class LLLandSit : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
if (gAgent.isSitting())
{
gAgent.standUp();
}
LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
LLQuaternion target_rot;

View File

@ -38,7 +38,7 @@
#include "llfloatermap.h"
#include "llfloatermodelpreview.h"
#include "llfloatersnapshot.h"
#include "llfloateroutfitsnapshot.h"
#include "llfloatersimpleoutfitsnapshot.h"
#include "llimage.h"
#include "llimagebmp.h"
#include "llimagepng.h"
@ -664,7 +664,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance();
LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance();
bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain())
|| (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain());
bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
@ -681,7 +681,7 @@ class LLFileCloseAllWindows : public view_listener_t
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
if (floater_snapshot)
floater_snapshot->closeFloater(app_quitting);
LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance();
LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance();
if (floater_outfit_snapshot)
floater_outfit_snapshot->closeFloater(app_quitting);
if (gMenuHolder) gMenuHolder->hideMenus();

View File

@ -316,7 +316,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mLastUpdateType(OUT_UNKNOWN),
mLastUpdateCached(FALSE),
mCachedMuteListUpdateTime(0),
mCachedOwnerInMuteList(false)
mCachedOwnerInMuteList(false),
mRiggedAttachedWarned(false)
{
if (!is_global)
{

Some files were not shown because too many files have changed in this diff Show More