diff options
199 files changed, 26397 insertions, 2229 deletions
diff --git a/.gitignore b/.gitignore index e949cddb22..f33da3c8b3 100644 --- a/.gitignore +++ b/.gitignore @@ -282,3 +282,5 @@ src/qml/RegExpJitTables.h src/qml/udis86_itab.c src/qml/udis86_itab.h +# Generated HLSL bytecode headers +*.hlslh diff --git a/LICENSE.PREVIEW.COMMERCIAL b/LICENSE.PREVIEW.COMMERCIAL new file mode 100644 index 0000000000..1f59ab24f3 --- /dev/null +++ b/LICENSE.PREVIEW.COMMERCIAL @@ -0,0 +1,627 @@ +TECHNOLOGY PREVIEW LICENSE AGREEMENT + +For individuals and/or legal entities resident in the Americas (North +America, Central America and South America), the applicable licensing +terms are specified under the heading "Technology Preview License +Agreement: The Americas". + +For individuals and/or legal entities not resident in The Americas, the +applicable licensing terms are specified under the heading "Technology +Preview License Agreement: Rest of the World". + + +TECHNOLOGY PREVIEW LICENSE AGREEMENT: The Americas +Agreement version 2.4 + +This Technology Preview License Agreement ("Agreement")is a legal agreement +between The Qt Company USA, Inc. ("The Qt Company"), with its registered +office at 2350 Mission College Blvd., Suite 1020, Santa Clara, California +95054, U.S.A. and you (either an individual or a legal entity) ("Licensee") +for the Licensed Software (as defined below). + +1. DEFINITIONS + +"Affiliate" of a Party shall mean an entity (i) which is directly or +indirectly controlling such Party; (ii) which is under the same direct +or indirect ownership or control as such Party; or (iii) which is +directly or indirectly owned or controlled by such Party. For these +purposes, an entity shall be treated as being controlled by another if +that other entity has fifty percent (50 %) or more of the votes in such +entity, is able to direct its affairs and/or to control the composition +of its board of directors or equivalent body. + +"Applications" shall mean Licensee's software products created using the +Licensed Software which may include portions of the Licensed Software. + +"Term" shall mean the period of time six (6) months from the later of +(a) the Effective Date; or (b) the date the Licensed Software was +initially delivered to Licensee by The Qt Company. If no specific Effective +Date is set forth in the Agreement, the Effective Date shall be deemed to be +the date the Licensed Software was initially delivered to Licensee. + +"Licensed Software" shall mean the computer software, "online" or +electronic documentation, associated media and printed materials, +including the source code, example programs and the documentation +delivered by The Qt Company to Licensee in conjunction with this Agreement. + +"Party" or "Parties" shall mean Licensee and/or The Qt Company. + + +2. OWNERSHIP + +The Licensed Software is protected by copyright laws and international +copyright treaties, as well as other intellectual property laws and +treaties. The Licensed Software is licensed, not sold. + +If Licensee provides any findings, proposals, suggestions or other +feedback ("Feedback") to The Qt Company regarding the Licensed Software, +The Qt Company shall own all right, title and interest including the +intellectual property rights in and to such Feedback, excluding however any +existing patent rights of Licensee. To the extent Licensee owns or controls +any patents for such Feedback Licensee hereby grants to The Qt Company and its +Affiliates, a worldwide, perpetual, non-transferable, sublicensable, +royalty-free license to (i) use, copy and modify Feedback and to create +derivative works thereof, (ii) to make (and have made), use, import, +sell, offer for sale, lease, dispose, offer for disposal or otherwise +exploit any products or services of The Qt Company containing Feedback, and +(iii) sublicense all the foregoing rights to third party licensees and +customers of The Qt Company and/or its Affiliates. + + +3. VALIDITY OF THE AGREEMENT + +By installing, copying, or otherwise using the Licensed Software, +Licensee agrees to be bound by the terms of this Agreement. If Licensee +does not agree to the terms of this Agreement, Licensee may not install, +copy, or otherwise use the Licensed Software. Upon Licensee's acceptance +of the terms and conditions of this Agreement, The Qt Company grants Licensee +the right to use the Licensed Software in the manner provided below. + + +4. LICENSES + +4.1. Using and Copying + +The Qt Company grants to Licensee a non-exclusive, non-transferable, +time-limited license to use and copy the Licensed Software for sole purpose +of designing, developing and testing Applications, and evaluating and the +Licensed Software during the Term. + +Licensee may install copies of the Licensed Software on an unlimited +number of computers provided that (a) if an individual, only such +individual; or (b) if a legal entity only its employees; use the +Licensed Software for the authorized purposes. + +4.2 No Distribution or Modifications + +Licensee may not disclose, modify, sell, market, commercialise, +distribute, loan, rent, lease, or license the Licensed Software or any +copy of it or use the Licensed Software for any purpose that is not +expressly granted in this Section 4. Licensee may not alter or remove +any details of ownership, copyright, trademark or other property right +connected with the Licensed Software. Licensee may not distribute any +software statically or dynamically linked with the Licensed Software. + +4.3 No Technical Support + +The Qt Company has no obligation to furnish Licensee with any technical +support whatsoever. Any such support is subject to separate agreement between +the Parties. + + +5. PRE-RELEASE CODE +The Licensed Software contains pre-release code that is not at the level +of performance and compatibility of a final, generally available, +product offering. The Licensed Software may not operate correctly and +may be substantially modified prior to the first commercial product +release, if any. The Qt Company is not obligated to make this or any later +version of the Licensed Software commercially available. The License +Software is "Not for Commercial Use" and may only be used for the +purposes described in Section 4. The Licensed Software may not be used +in a live operating environment where it may be relied upon to perform +in the same manner as a commercially released product or with data that +has not been sufficiently backed up. + +6. THIRD PARTY SOFTWARE + +The Licensed Software may provide links to third party libraries or code +(collectively "Third Party Software") to implement various functions. +Third Party Software does not comprise part of the Licensed Software. In +some cases, access to Third Party Software may be included along with +the Licensed Software delivery as a convenience for development and +testing only. Such source code and libraries may be listed in the +".../src/3rdparty" source tree delivered with the Licensed Software or +documented in the Licensed Software where the Third Party Software is +used, as may be amended from time to time, do not comprise the Licensed +Software. Licensee acknowledges (1) that some part of Third Party +Software may require additional licensing of copyright and patents from +the owners of such, and (2) that distribution of any of the Licensed +Software referencing any portion of a Third Party Software may require +appropriate licensing from such third parties. + + +7. LIMITED WARRANTY AND WARRANTY DISCLAIMER + +The Licensed Software is licensed to Licensee "as is". To the maximum +extent permitted by applicable law, The Qt Company on behalf of itself and +its suppliers, disclaims all warranties and conditions, either express or +implied, including, but not limited to, implied warranties of +merchantability, fitness for a particular purpose, title and +non-infringement with regard to the Licensed Software. + + +8. LIMITATION OF LIABILITY + +If, The Qt Company's warranty disclaimer notwithstanding, The Qt Company is +held liable to Licensee, whether in contract, tort or any other legal theory, +based on the Licensed Software, The Qt Company's entire liability to Licensee +and Licensee's exclusive remedy shall be, at The Qt Company's option, either +(A) return of the price Licensee paid for the Licensed Software, or (B) +repair or replacement of the Licensed Software, provided Licensee +returns to The Qt Company all copies of the Licensed Software as originally +delivered to Licensee. The Qt Company shall not under any circumstances be +liable to Licensee based on failure of the Licensed Software if the failure +resulted from accident, abuse or misapplication, nor shall The Qt Company +under any circumstances be liable for special damages, punitive or exemplary +damages, damages for loss of profits or interruption of business or for +loss or corruption of data. Any award of damages from The Qt Company to +Licensee shall not exceed the total amount Licensee has paid to The Qt +Company in connection with this Agreement. + + +9. CONFIDENTIALITY + +Each party acknowledges that during the Term of this Agreement it shall +have access to information about the other party's business, business +methods, business plans, customers, business relations, technology, and +other information, including the terms of this Agreement, that is +confidential and of great value to the other party, and the value of +which would be significantly reduced if disclosed to third parties (the +"Confidential Information"). Accordingly, when a party (the "Receiving +Party") receives Confidential Information from another party (the +"Disclosing Party"), the Receiving Party shall, and shall obligate its +employees and agents and employees and agents of its Affiliates to: (i) +maintain the Confidential Information in strict confidence; (ii) not +disclose the Confidential Information to a third party without the +Disclosing Party's prior written approval; and (iii) not, directly or +indirectly, use the Confidential Information for any purpose other than +for exercising its rights and fulfilling its responsibilities pursuant +to this Agreement. Each party shall take reasonable measures to protect +the Confidential Information of the other party, which measures shall +not be less than the measures taken by such party to protect its own +confidential and proprietary information. + +"Confidential Information" shall not include information that (a) is or +becomes generally known to the public through no act or omission of the +Receiving Party; (b) was in the Receiving Party's lawful possession +prior to the disclosure hereunder and was not subject to limitations on +disclosure or use; (c) is developed by the Receiving Party without +access to the Confidential Information of the Disclosing Party or by +persons who have not had access to the Confidential Information of the +Disclosing Party as proven by the written records of the Receiving +Party; (d) is lawfully disclosed to the Receiving Party without +restrictions, by a third party not under an obligation of +confidentiality; or (e) the Receiving Party is legally compelled to +disclose the information, in which case the Receiving Party shall assert +the privileged and confidential nature of the information and cooperate +fully with the Disclosing Party to protect against and prevent +disclosure of any Confidential Information and to limit the scope of +disclosure and the dissemination of disclosed Confidential Information +by all legally available means. + +The obligations of the Receiving Party under this Section shall continue +during the Initial Term and for a period of five (5) years after +expiration or termination of this Agreement. To the extent that the +terms of the Non-Disclosure Agreement between The Qt Company and Licensee +conflict with the terms of this Section 9, this Section 9 shall be +controlling over the terms of the Non-Disclosure Agreement. + + +10. GENERAL PROVISIONS + +10.1 No Assignment + +Licensee shall not be entitled to assign or transfer all or any of its +rights, benefits and obligations under this Agreement without the prior +written consent of The Qt Company, which shall not be unreasonably withheld. + +10.2 Termination + +The Qt Company may terminate the Agreement at any time immediately upon +written notice by The Qt Company to Licensee if Licensee breaches this +Agreement. + +Upon termination of this Agreement, Licensee shall return to The Qt Company +all copies of Licensed Software that were supplied by The Qt Company. All +other copies of Licensed Software in the possession or control of Licensee +must be erased or destroyed. An officer of Licensee must promptly +deliver to The Qt Company a written confirmation that this has occurred. + +10.3 Surviving Sections + +Any terms and conditions that by their nature or otherwise reasonably +should survive a cancellation or termination of this Agreement shall +also be deemed to survive. Such terms and conditions include, but are +not limited to the following Sections: 2, 5, 6, 7, 8, 9, 10.2, 10.3, 10.4, +10.5, 10.6, 10.7, and 10.8 of this Agreement. + +10.4 Entire Agreement + +This Agreement constitutes the complete agreement between the parties +and supersedes all prior or contemporaneous discussions, +representations, and proposals, written or oral, with respect to the +subject matters discussed herein, with the exception of the +non-disclosure agreement executed by the parties in connection with this +Agreement ("Non-Disclosure Agreement"), if any, shall be subject to +Section 9. No modification of this Agreement shall be effective unless +contained in a writing executed by an authorized representative of each +party. No term or condition contained in Licensee's purchase order shall +apply unless expressly accepted by The Qt Company in writing. If any +provision of the Agreement is found void or unenforceable, the remainder +shall remain valid and enforceable according to its terms. If any remedy +provided is determined to have failed for its essential purpose, all +limitations of liability and exclusions of damages set forth in this +Agreement shall remain in effect. + +10.5 Export Control + +Licensee acknowledges that the Licensed Software may be subject to +export control restrictions of various countries. Licensee shall fully +comply with all applicable export license restrictions and requirements +as well as with all laws and regulations relating to the importation of +the Licensed Software and shall procure all necessary governmental +authorizations, including without limitation, all necessary licenses, +approvals, permissions or consents, where necessary for the +re-exportation of the Licensed Software., + +10.6 Governing Law and Legal Venue + +This Agreement shall be governed by and construed in accordance with the +federal laws of the United States of America and the internal laws of +the State of New York without given effect to any choice of law rule +that would result in the application of the laws of any other +jurisdiction. The United Nations Convention on Contracts for the +International Sale of Goods (CISG) shall not apply. Each Party (a) +hereby irrevocably submits itself to and consents to the jurisdiction of +the United States District Court for the Southern District of New York +(or if such court lacks jurisdiction, the state courts of the State of +New York) for the purposes of any action, claim, suit or proceeding +between the Parties in connection with any controversy, claim, or +dispute arising out of or relating to this Agreement; and (b) hereby +waives, and agrees not to assert by way of motion, as a defense or +otherwise, in any such action, claim, suit or proceeding, any claim that +is not personally subject to the jurisdiction of such court(s), that the +action, claim, suit or proceeding is brought in an inconvenient forum or +that the venue of the action, claim, suit or proceeding is improper. +Notwithstanding the foregoing, nothing in this Section 9.6 is intended +to, or shall be deemed to, constitute a submission or consent to, or +selection of, jurisdiction, forum or venue for any action for patent +infringement, whether or not such action relates to this Agreement. + +10.7 No Implied License + +There are no implied licenses or other implied rights granted under this +Agreement, and all rights, save for those expressly granted hereunder, +shall remain with The Qt Company and its licensors. In addition, no licenses +or immunities are granted to the combination of the Licensed Software with +any other software or hardware not delivered by The Qt Company under this +Agreement. + +10.8 Government End Users + +A "U.S. Government End User" shall mean any agency or entity of the +government of the United States. The following shall apply if Licensee +is a U.S. Government End User. The Licensed Software is a "commercial +item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), +consisting of "commercial computer software" and "commercial computer +software documentation," as such terms are used in 48 C.F.R. 12.212 +(Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 +through 227.7202-4 (June 1995), all U.S. Government End Users acquire +the Licensed Software with only those rights set forth herein. The +Licensed Software (including related documentation) is provided to U.S. +Government End Users: (a) only as a commercial end item; and (b) only +pursuant to this Agreement. + + + + + +TECHNOLOGY PREVIEW LICENSE AGREEMENT: Rest of the World +Agreement version 2.4 + +This Technology Preview License Agreement ("Agreement") is a legal +agreement between The Qt Company Ltd ("The Qt Company"), with its registered +office at Valimotie 21,FI-00380 Helsinki, Finland and you (either an +individual or a legal entity) ("Licensee") for the Licensed Software. + +1. DEFINITIONS + +"Affiliate" of a Party shall mean an entity (i) which is directly or +indirectly controlling such Party; (ii) which is under the same direct +or indirect ownership or control as such Party; or (iii) which is +directly or indirectly owned or controlled by such Party. For these +purposes, an entity shall be treated as being controlled by another if +that other entity has fifty percent (50 %) or more of the votes in such +entity, is able to direct its affairs and/or to control the composition +of its board of directors or equivalent body. + +"Applications" shall mean Licensee's software products created using the +Licensed Software which may include portions of the Licensed Software. + +"Term" shall mean the period of time six (6) months from the later of +(a) the Effective Date; or (b) the date the Licensed Software was +initially delivered to Licensee by The Qt Company. If no specific Effective +Date is set forth in the Agreement, the Effective Date shall be deemed to be +the date the Licensed Software was initially delivered to Licensee. + +"Licensed Software" shall mean the computer software, "online" or +electronic documentation, associated media and printed materials, +including the source code, example programs and the documentation +delivered by The Qt Company to Licensee in conjunction with this Agreement. + +"Party" or "Parties" shall mean Licensee and/or The Qt Company. + + +2. OWNERSHIP + +The Licensed Software is protected by copyright laws and international +copyright treaties, as well as other intellectual property laws and +treaties. The Licensed Software is licensed, not sold. + +If Licensee provides any findings, proposals, suggestions or other +feedback ("Feedback") to The Qt Company regarding the Licensed Software, +The Qt Companyshall own all right, title and interest including the +intellectual property rights in and to such Feedback, excluding however any +existing patent rights of Licensee. To the extent Licensee owns or controls +any patents for such Feedback Licensee hereby grants to The Qt Company and +its Affiliates, a worldwide, perpetual, non-transferable, sublicensable, +royalty-free license to (i) use, copy and modify Feedback and to create +derivative works thereof, (ii) to make (and have made), use, import, +sell, offer for sale, lease, dispose, offer for disposal or otherwise +exploit any products or services of The Qt Company containing Feedback, and +(iii) sublicense all the foregoing rights to third party licensees and +customers of The Qt Company and/or its Affiliates. + +3. VALIDITY OF THE AGREEMENT + +By installing, copying, or otherwise using the Licensed Software, +Licensee agrees to be bound by the terms of this Agreement. If Licensee +does not agree to the terms of this Agreement, Licensee may not install, +copy, or otherwise use the Licensed Software. Upon Licensee's acceptance +of the terms and conditions of this Agreement, The Qt Company grants Licensee +the right to use the Licensed Software in the manner provided below. + + +4. LICENSES + +4.1. Using and Copying + +The Qt Company grants to Licensee a non-exclusive, non-transferable, +time-limited license to use and copy the Licensed Software for sole purpose +of designing, developing and testing Applications, and evaluating and the +Licensed Software during the Term. + +Licensee may install copies of the Licensed Software on an unlimited +number of computers provided that (a) if an individual, only such +individual; or (b) if a legal entity only its employees; use the +Licensed Software for the authorized purposes. + +4.2 No Distribution or Modifications + +Licensee may not disclose, modify, sell, market, commercialise, +distribute, loan, rent, lease, or license the Licensed Software or any +copy of it or use the Licensed Software for any purpose that is not +expressly granted in this Section 4. Licensee may not alter or remove +any details of ownership, copyright, trademark or other property right +connected with the Licensed Software. Licensee may not distribute any +software statically or dynamically linked with the Licensed Software. + +4.3 No Technical Support + +The Qt Company has no obligation to furnish Licensee with any technical +support whatsoever. Any such support is subject to separate agreement +between the Parties. + + +5. PRE-RELEASE CODE + +The Licensed Software contains pre-release code that is not at the level +of performance and compatibility of a final, generally available, +product offering. The Licensed Software may not operate correctly and +may be substantially modified prior to the first commercial product +release, if any. The Qt Company is not obligated to make this or any later +version of the Licensed Software commercially available. The License +Software is "Not for Commercial Use" and may only be used for the +purposes described in Section 4. The Licensed Software may not be used +in a live operating environment where it may be relied upon to perform +in the same manner as a commercially released product or with data that +has not been sufficiently backed up. + +6. THIRD PARTY SOFTWARE + +The Licensed Software may provide links to third party libraries or code +(collectively "Third Party Software") to implement various functions. +Third Party Software does not comprise part of the Licensed Software. In +some cases, access to Third Party Software may be included along with +the Licensed Software delivery as a convenience for development and +testing only. Such source code and libraries may be listed in the +".../src/3rdparty" source tree delivered with the Licensed Software or +documented in the Licensed Software where the Third Party Software is +used, as may be amended from time to time, do not comprise the Licensed +Software. Licensee acknowledges (1) that some part of Third Party +Software may require additional licensing of copyright and patents from +the owners of such, and (2) that distribution of any of the Licensed +Software referencing any portion of a Third Party Software may require +appropriate licensing from such third parties. + + +7. LIMITED WARRANTY AND WARRANTY DISCLAIMER + +The Licensed Software is licensed to Licensee "as is". To the maximum +extent permitted by applicable law, The Qt Company on behalf of itself and +its suppliers, disclaims all warranties and conditions, either express or +implied, including, but not limited to, implied warranties of +merchantability, fitness for a particular purpose, title and +non-infringement with regard to the Licensed Software. + + +8. LIMITATION OF LIABILITY + +If, The Qt Company's warranty disclaimer notwithstanding, The Qt Company is +held liable to Licensee, whether in contract, tort or any other legal theory, +based on the Licensed Software, The Qt Company's entire liability to Licensee +and Licensee's exclusive remedy shall be, at The Qt Company's option, either +(A) return of the price Licensee paid for the Licensed Software, or (B) +repair or replacement of the Licensed Software, provided Licensee +returns to The Qt Company all copies of the Licensed Software as originally +delivered to Licensee. The Qt Company shall not under any circumstances be +liable to Licensee based on failure of the Licensed Software if the failure +resulted from accident, abuse or misapplication, nor shall The Qt Company +under any circumstances be liable for special damages, punitive or exemplary +damages, damages for loss of profits or interruption of business or for +loss or corruption of data. Any award of damages from The Qt Company to +Licensee shall not exceed the total amount Licensee has paid to +The Qt Company in connection with this Agreement. + + +9. CONFIDENTIALITY + +Each party acknowledges that during the Term of this Agreement it shall +have access to information about the other party's business, business +methods, business plans, customers, business relations, technology, and +other information, including the terms of this Agreement, that is +confidential and of great value to the other party, and the value of +which would be significantly reduced if disclosed to third parties (the +"Confidential Information"). Accordingly, when a party (the "Receiving +Party") receives Confidential Information from another party (the +"Disclosing Party"), the Receiving Party shall, and shall obligate its +employees and agents and employees and agents of its Affiliates to: (i) +maintain the Confidential Information in strict confidence; (ii) not +disclose the Confidential Information to a third party without the +Disclosing Party's prior written approval; and (iii) not, directly or +indirectly, use the Confidential Information for any purpose other than +for exercising its rights and fulfilling its responsibilities pursuant +to this Agreement. Each party shall take reasonable measures to protect +the Confidential Information of the other party, which measures shall +not be less than the measures taken by such party to protect its own +confidential and proprietary information. + +"Confidential Information" shall not include information that (a) is or +becomes generally known to the public through no act or omission of the +Receiving Party; (b) was in the Receiving Party's lawful possession +prior to the disclosure hereunder and was not subject to limitations on +disclosure or use; (c) is developed by the Receiving Party without +access to the Confidential Information of the Disclosing Party or by +persons who have not had access to the Confidential Information of the +Disclosing Party as proven by the written records of the Receiving +Party; (d) is lawfully disclosed to the Receiving Party without +restrictions, by a third party not under an obligation of +confidentiality; or (e) the Receiving Party is legally compelled to +disclose the information, in which case the Receiving Party shall assert +the privileged and confidential nature of the information and cooperate +fully with the Disclosing Party to protect against and prevent +disclosure of any Confidential Information and to limit the scope of +disclosure and the dissemination of disclosed Confidential Information +by all legally available means. + +The obligations of the Receiving Party under this Section shall continue +during the Initial Term and for a period of five (5) years after +expiration or termination of this Agreement. To the extent that the +terms of the Non-Disclosure Agreement between The Qt Company and Licensee +conflict with the terms of this Section 9, this Section 9 shall be +controlling over the terms of the Non-Disclosure Agreement. + + +10. GENERAL PROVISIONS + +10.1 No Assignment + +Licensee shall not be entitled to assign or transfer all or any of its +rights, benefits and obligations under this Agreement without the prior +written consent of The Qt Company, which shall not be unreasonably withheld. + +10.2 Termination + +The Qt Company may terminate the Agreement at any time immediately upon +written notice by The Qt Company to Licensee if Licensee breaches this +Agreement. + +Upon termination of this Agreement, Licensee shall return to The Qt Company +all copies of Licensed Software that were supplied by The Qt Company. All +other copies of Licensed Software in the possession or control of Licensee +must be erased or destroyed. An officer of Licensee must promptly +deliver to The Qt Company a written confirmation that this has occurred. + +10.3 Surviving Sections + +Any terms and conditions that by their nature or otherwise reasonably +should survive a cancellation or termination of this Agreement shall +also be deemed to survive. Such terms and conditions include, but are +not limited to the following Sections: 2, 5, 6, 7, 8, 9, 10.2, 10.3, 10.4, +10.5, 10.6, 10.7, and 10.8 of this Agreement. + +10.4 Entire Agreement + +This Agreement constitutes the complete agreement between the parties +and supersedes all prior or contemporaneous discussions, +representations, and proposals, written or oral, with respect to the +subject matters discussed herein, with the exception of the +non-disclosure agreement executed by the parties in connection with this +Agreement ("Non-Disclosure Agreement"), if any, shall be subject to +Section 9. No modification of this Agreement shall be effective unless +contained in a writing executed by an authorized representative of each +party. No term or condition contained in Licensee's purchase order shall +apply unless expressly accepted by The Qt Company in writing. If any provision +of the Agreement is found void or unenforceable, the remainder shall remain +valid and enforceable according to its terms. If any remedy provided is +determined to have failed for its essential purpose, all limitations of +liability and exclusions of damages set forth in this Agreement shall +remain in effect. + +10.5 Export Control + +Licensee acknowledges that the Licensed Software may be subject to +export control restrictions of various countries. Licensee shall fully +comply with all applicable export license restrictions and requirements +as well as with all laws and regulations relating to the importation of +the Licensed Software and shall procure all necessary governmental +authorizations, including without limitation, all necessary licenses, +approvals, permissions or consents, where necessary for the +re-exportation of the Licensed Software., + +10.6 Governing Law and Legal Venue + +This Agreement shall be construed and interpreted in accordance with the +laws of Finland, excluding its choice of law provisions. Any disputes +arising out of or relating to this Agreement shall be resolved in +arbitration under the Rules of Arbitration of the Chamber of Commerce of +Helsinki, Finland. The arbitration tribunal shall consist of one (1), or +if either Party so requires, of three (3), arbitrators. The award shall +be final and binding and enforceable in any court of competent +jurisdiction. The arbitration shall be held in Helsinki, Finland and the +process shall be conducted in the English language. + +10.7 No Implied License + +There are no implied licenses or other implied rights granted under this +Agreement, and all rights, save for those expressly granted hereunder, +shall remain with The Qt Company and its licensors. In addition, no licenses +or immunities are granted to the combination of the Licensed Software with +any other software or hardware not delivered by The Qt Company under this +Agreement. + +10.8 Government End Users + +A "U.S. Government End User" shall mean any agency or entity of the +government of the United States. The following shall apply if Licensee +is a U.S. Government End User. The Licensed Software is a "commercial +item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), +consisting of "commercial computer software" and "commercial computer +software documentation," as such terms are used in 48 C.F.R. 12.212 +(Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 +through 227.7202-4 (June 1995), all U.S. Government End Users acquire +the Licensed Software with only those rights set forth herein. The +Licensed Software (including related documentation) is provided to U.S. +Government End Users: (a) only as a commercial end item; and (b) only +pursuant to this Agreement. + diff --git a/config.tests/d3d12/d3d12.cpp b/config.tests/d3d12/d3d12.cpp new file mode 100644 index 0000000000..0bf90cc457 --- /dev/null +++ b/config.tests/d3d12/d3d12.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <d3d12.h> +#include <dxgi1_4.h> +#include <wrl/client.h> + +using namespace Microsoft::WRL; + +int main(int, char **) +{ + ID3D12Device *dev = 0; + + return 0; +} diff --git a/config.tests/d3d12/d3d12.pro b/config.tests/d3d12/d3d12.pro new file mode 100644 index 0000000000..24c5991a4b --- /dev/null +++ b/config.tests/d3d12/d3d12.pro @@ -0,0 +1,4 @@ +SOURCES = d3d12.cpp +CONFIG -= qt dylib +CONFIG += console +LIBS += -ldxgi -ld3d12 diff --git a/features/hlsl_bytecode_header.prf b/features/hlsl_bytecode_header.prf new file mode 100644 index 0000000000..0fa27a75d5 --- /dev/null +++ b/features/hlsl_bytecode_header.prf @@ -0,0 +1,10 @@ +for (SHADER, HLSL_SHADERS) { + INPUT = $$eval($${SHADER}.input) + fxc_$${SHADER}.input = $$INPUT + fxc_$${SHADER}.commands = fxc.exe /nologo /E $$eval($${SHADER}.entry) /T $$eval($${SHADER}.type) /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME} + fxc_$${SHADER}.output = $$eval($${SHADER}.header) + fxc_$${SHADER}.dependency_type = TYPE_C + fxc_$${SHADER}.variable_out = HEADERS + fxc_$${SHADER}.CONFIG += target_predeps + QMAKE_EXTRA_COMPILERS += fxc_$${SHADER} +} diff --git a/qtdeclarative.pro b/qtdeclarative.pro index 5b94da9b69..c9df6e053b 100644 --- a/qtdeclarative.pro +++ b/qtdeclarative.pro @@ -1,3 +1,6 @@ +load(configure) +qtCompileTest(d3d12) + CONFIG += tests_need_tools examples_need_tools load(qt_parts) diff --git a/src/doc/config/qtquick2drenderer.qdocconf b/src/doc/config/qtquick2drenderer.qdocconf new file mode 100644 index 0000000000..7bb57b3b3e --- /dev/null +++ b/src/doc/config/qtquick2drenderer.qdocconf @@ -0,0 +1,35 @@ +include($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf) +include($QT_INSTALL_DOCS/global/qt-cpp-defines.qdocconf) +include($QT_INSTALL_DOCS/global/fileextensions.qdocconf) + +naturallanguate = en_US +outputencoding = UTF-8 +sourceencoding = UTF-8 + +projects = QtQuick2dRenderer +url = http://doc.qt.io/QtQuick2DRenderer +description = Qt Quick 2D Renderer Documentation +version = $QT_VERSION + +sourcedirs += ../src +imagedirs += ../images + +qhp.projects = QtQuick2dRenderer + +qhp.QtQuick2dRenderer.file = qtquick2drenderer.qhp +qhp.QtQuick2dRenderer.namespace = com.digia.qtquick2drenderer.$QT_VERSION_TAG +qhp.QtQuick2dRenderer.virtualFolder = qtquick2drenderer +qhp.QtQuick2dRenderer.indexTitle = Qt Quick 2D Renderer +qhp.QtQuick2dRenderer.indexRoot = + +qhp.QtQuick2dRenderer.subprojects = manual +qhp.QtQuick2dRenderer.manual.index = Qt Quick 2D Renderer +qhp.QtQuick2dRenderer.manual.indexTitle = Qt Quick 2D Renderer +qhp.QtQuick2dRenderer.manual.type = manual + +macro.RENDERER = "Qt Quick 2D Renderer" + +navigation.landingpage = "Qt Quick 2D Renderer" +indexes = $QT_INSTALL_DOCS/qtgui/qtgui.index \ + $QT_INSTALL_DOCS/qtquick/qtquick.index \ + $QT_INSTALL_DOCS/qtgraphicaleffects/qtgraphicaleffects.index diff --git a/src/doc/doc.pro b/src/doc/doc.pro new file mode 100644 index 0000000000..1077195338 --- /dev/null +++ b/src/doc/doc.pro @@ -0,0 +1,9 @@ +TEMPLATE = aux +QMAKE_DOCS = $$PWD/config/qtquick2drenderer.qdocconf + +OTHER_FILES += \ + $$PWD/config/qtquick2drenderer.qdocconf \ + $$PWD/src/qtquick2drenderer-index.qdoc \ + $$PWD/src/qtquick2drenderer-installation-guide.qdoc \ + $$PWD/src/qtquick2drenderer-performance.qdoc \ + $$PWD/src/qtquick2drenderer-limitations.qdoc diff --git a/src/doc/src/qtquick2drenderer-index.qdoc b/src/doc/src/qtquick2drenderer-index.qdoc new file mode 100644 index 0000000000..52eed811a3 --- /dev/null +++ b/src/doc/src/qtquick2drenderer-index.qdoc @@ -0,0 +1,51 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick 2d Renderer module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + +/*! + \contentspage{index.html}{Qt Quick 2D Renderer} + \page index.html + \nextpage qtquick2drenderer-installation-guide.html + \title Qt Quick 2D Renderer + + \RENDERER is an alternative renderer for \l {Qt Quick} 2 that uses the Raster + paint engine to render the contents of the scene graph instead of OpenGL. + As a result of not using OpenGL to render the scene graph, some features + and optimizations are no longer available. Most Qt Quick 2 applications + will run without modification though any attempts to use unsupported + features will be ignored. By using the \RENDERER it is now possible to run Qt + Quick 2 applications on hardware and platforms that do not have OpenGL + support. + + \RENDERER is a Qt module that contains a scene graph renderer plugin. + + To use \RENDERER add the following to your run environment: + \badcode + export QMLSCENE_DEVICE=softwarecontext + \endcode + + \section1 Contents + + \list + \li \l{Installation Guide} + \li \l{Limitations} + \li \l{Performance Guide} + \endlist +*/ diff --git a/src/doc/src/qtquick2drenderer-installation-guide.qdoc b/src/doc/src/qtquick2drenderer-installation-guide.qdoc new file mode 100644 index 0000000000..e18b09272c --- /dev/null +++ b/src/doc/src/qtquick2drenderer-installation-guide.qdoc @@ -0,0 +1,120 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick 2d Renderer module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + +/*! + \page qtquick2drenderer-installation-guide.html + \previouspage index.html + \nextpage qtquick2drenderer-limitations.html + + \title Installation Guide + + The building of \RENDERER is complicated by the fact that \l{Qt Quick} 2 + always requires OpenGL support regardless of whether it is being used or + not. You will need to build Qt with support for OpenGL even if the target + system does not support it. If you have a Qt build that already supports + OpenGL, you can skip to \l {building-renderer}{Building \RENDERER}. + + \section1 Providing the OpenGL Dependency + + \RENDERER works in such a way that it renders the Qt Quick 2 scene + graph with QPainter, instead of using hardware acceleration via the OpenGL API. + However, Qt Quick 2 still assumes that OpenGL is always available. With + \RENDERER we can avoid making OpenGL calls, but that does not change the + fact that QtQuick 2 requires the OpenGL development headers to be available + at build-time and will link against OpenGL libraries at run-time. + + The solution is to provide a dummy OpenGL library and development + headers to build Qt against. In this way you can build Qt with virtual OpenGL + support and get access to the QtQuick 2 APIs. You should have no problems + using \RENDERER provided that you use a platform plugin that does not make calls to + EGL or OpenGL commands, and that you refrain from using APIs that access OpenGL directly. + + \section1 How to use the OpenGL Dummy Libraries + + The OpenGL dummy libraries provide both headers and shared object files + containing the symbols for both OpenGL and EGL. The headers get copied + into your INCLUDE path, and the shared object files get copied into your LIB + path in both the sysroot, as well as in the target image distributed on the + device. The library that is generated contains all the symbols needed to + link an application as if you had support for OpenGL and EGL. It is important + to make sure that you do not call any of these symbols in your application. + + \section2 Prerequisites + + Three elements are required: + \list 1 + \li Toolchain to cross compile code for your device. + \li Sysroot containing development headers and shared objects to link + against when building applications. + \li Target image intended to be deployed to your device. + \endlist + + \section2 How to build the OpenGL Dummy Libraries + + Set up your build environment by defining where your compiler and sysroot + are located: + \badcode + export CC=/opt/arm-toolchain/usr/bin/arm-linux-gnueabi-g++ + export SYSROOT=/opt/device-name/sysroot/ + \endcode + Run the build script inside the client-dummy directory: + \badcode + cd client-dummy + ./build-gcc.sh + \endcode + That should generate two files: \c libEGL.so, \c libGLESv2.so + + \section2 Installation of Files + + Copy the include folder to the /usr/include folder in your sysroot. This + installs the OpenGL/EGL headers: + \badcode + cp -r 3rdparty/include/* ${SYSROOT}/usr/include/ + \endcode + Copy \c libEGL.so and \c libGLESv2.so to the /usr/lib folder in your sysroot: + \badcode + cp src/lib*.so ${SYSROOT}/usr/lib/ + \endcode + + Copy the \c libEGL.so and \c libGLESv2.so libraries to the target device image as well. + + \section1 Building Qt + + When configuring Qt, make sure to append \c {-opengl es2} to your configure arguments. + + \target building-renderer + \section1 Building \RENDERER + + Build \RENDERER like any other Qt module: + \badcode + qmake + make + make install + \endcode + + \section1 Deployment + + Now, when you deploy your Qt build to the device, it will depend on the dummy + libs \c libEGL.so and \c libGLESv2.so, but as long as you are using the \RENDERER + plugin you will be able to use Qt Quick 2 without actually making any + OpenGL or EGL calls. + +*/ diff --git a/src/doc/src/qtquick2drenderer-limitations.qdoc b/src/doc/src/qtquick2drenderer-limitations.qdoc new file mode 100644 index 0000000000..63c3f209f2 --- /dev/null +++ b/src/doc/src/qtquick2drenderer-limitations.qdoc @@ -0,0 +1,63 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick 2d Renderer module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + +/*! + \page qtquick2drenderer-limitations.html + \previouspage qtquick2drenderer-installation-guide.html + \nextpage qtquick2drenderer-performance.html + + \title Limitations + + \l {Qt Quick} 2 was designed to take full advantage of OpenGL to make the most + out of available graphics hardware. By not relying on OpenGL, \RENDERER + presents certain limitations regarding the available features. + + Since \RENDERER does not use OpenGL, there are some features that cannot be + supported. The following are known limitations: + + \section1 Shader Effects + ShaderEffect components in QtQuick 2 can not be rendered with \RENDERER. + + \section1 Qt Graphical Effects Module + \l {Qt Graphical Effects} uses ShaderEffect items to render effects. If you use + graphical effects from this module, then you should not hide the source + item so that the original item can still be rendered. + + \section1 Particle Effects + It is not possible to render particle effects with \RENDERER. Whenever + possible, remove particles completely from the scene. Otherwise they will still + require some processing, even though they are not visible with \RENDERER. + + \section1 Sprites + The Sprite item depends on inaccessible OpenGL functions and will + not be visible. + + \section1 Rendering Text + The text rendering with \RENDERER is based on software rasterization and does + not respond as well to transformations such as scaling as when using OpenGL. + The quality is similar to choosing \l [QML] {Text::renderType} + {Text.NativeRendering} with \l [QML] {Text} items. + + \section1 Render Control + QQuickRenderControl depends on OpenGL to function and will not function + with \RENDERER. Using QQuickRenderControl can lead to unexpected behavior + and crashes. +*/ diff --git a/src/doc/src/qtquick2drenderer-performance.qdoc b/src/doc/src/qtquick2drenderer-performance.qdoc new file mode 100644 index 0000000000..94fdfe13ca --- /dev/null +++ b/src/doc/src/qtquick2drenderer-performance.qdoc @@ -0,0 +1,80 @@ +/****************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick 2d Renderer module. +** +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** $QT_END_LICENSE$ +** +******************************************************************************/ + +/*! + \contentspage{index.html}{Qt Quick 2D Renderer} + \page qtquick2drenderer-performance.html + \previouspage qtquick2drenderer-limitations.html + + \title Performance Guide + + Since \RENDERER does not use OpenGL, we lose the ability to use many + optimizations that can improve rendering speed. To get the most out of + \RENDERER there are some guidelines that should be followed. + + \section1 2D Hardware Acceleration + + \RENDERER is designed to use operations that can be accelerated by 2D + acceleration hardware. 2D hardware acceleration uses platform plugins that take advantage of + the QBlitter API (like DirectFB). + + \section1 Animation + + It is important to keep in mind that with Qt Quick 2 the entire window will + need to be rendered every time a node in the scene graph is marked dirty. + There is no partial update mechanimism that will update only the dirty regions + of the window. This means that any animation that is running will be forcing + a full repaint of the window, and with \RENDERER this can cause a heavy CPU load. + + \section1 Transforms + + Transformations come with no performance penalty when rendering the scene + graph with the OpenGL renderer. This is not the case with \RENDERER. + Translation operations do not come with performance penalties, but scaling + and rotation transformations should be avoided whenever possible. + + \section1 Hidden Items + + \RENDERER will paint all items that are not hidden explicitly with either + the visibility property or with an opacity of 0. Without OpenGL there is no + depth buffer to check for items completely obscured by opaque items, so + everything will be painted - even if it is unnecessary. + + \section1 Pixel Fill Budget + + When developing an application that will be using \RENDERER, it is important + to keep in mind your pixel fill budget, or the the amount of pixels you + can push to the screen in the time needed for your target framerate. For + example, if your goal is to render your application at 60 frames per second, + then you have about 16 milliseconds render to the framebuffer before + needing to flush the pixels to the screen. Depending on your hardware's + performance, you will only be able to handle a finite amount of pixel write + operations before the 16 milliseconds expire. The interface you design + should take into consideration that each added item subtracts from + your pixel fill budget. + + \RENDERER uses the painters algorithm to paint each item in the scene + back-to-front. If you have an interface that stacks many items on top of + each other, keep in mind that each layer is painted completely, not just the + parts that are visible. It can be very easy to waste your pixel fill + budget with too many over-paints. + +*/ diff --git a/src/imports/imports.pro b/src/imports/imports.pro index ff7b6e75af..67a357f909 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -12,9 +12,13 @@ qtHaveModule(quick) { SUBDIRS += \ layouts \ qtquick2 \ - particles \ window \ testlib + + contains(QT_CONFIG, opengl(es1|es2)?) { + SUBDIRS += \ + particles + } } qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 273407c19d..70a1eb22b6 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,2 +1,3 @@ TEMPLATE = subdirs + !contains(QT_CONFIG, no-qml-debug):SUBDIRS += qmltooling diff --git a/src/quick/designer/qquickdesignersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp index 5bb36c5192..ec00eed18a 100644 --- a/src/quick/designer/qquickdesignersupport.cpp +++ b/src/quick/designer/qquickdesignersupport.cpp @@ -92,6 +92,7 @@ void QQuickDesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool h texture->setRect(referencedItem->boundingRect()); texture->setSize(referencedItem->boundingRect().size().toSize()); texture->setRecursive(true); +#ifndef QT_NO_OPENGL #ifndef QT_OPENGL_ES if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) texture->setFormat(GL_RGBA8); @@ -100,6 +101,7 @@ void QQuickDesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool h #else texture->setFormat(GL_RGBA); #endif +#endif texture->setHasMipmaps(false); m_itemTextureHash.insert(referencedItem, texture); diff --git a/src/quick/designer/qquickdesignerwindowmanager.cpp b/src/quick/designer/qquickdesignerwindowmanager.cpp index efa3bcb51a..2d37db08e7 100644 --- a/src/quick/designer/qquickdesignerwindowmanager.cpp +++ b/src/quick/designer/qquickdesignerwindowmanager.cpp @@ -39,8 +39,9 @@ #include "qquickdesignerwindowmanager_p.h" #include "private/qquickwindow_p.h" -#include <QtGui/QOpenGLContext> - +#ifndef QT_NO_OPENGL +# include <QtQuick/private/qsgdefaultrendercontext_p.h> +#endif #include <QtQuick/QQuickWindow> QT_BEGIN_NAMESPACE @@ -48,7 +49,7 @@ QT_BEGIN_NAMESPACE QQuickDesignerWindowManager::QQuickDesignerWindowManager() : m_sgContext(QSGContext::createDefaultContext()) { - m_renderContext.reset(new QSGRenderContext(m_sgContext.data())); + m_renderContext.reset(m_sgContext.data()->createRenderContext()); } void QQuickDesignerWindowManager::show(QQuickWindow *window) @@ -66,6 +67,7 @@ void QQuickDesignerWindowManager::windowDestroyed(QQuickWindow *) void QQuickDesignerWindowManager::makeOpenGLContext(QQuickWindow *window) { +#ifndef QT_NO_OPENGL if (!m_openGlContext) { m_openGlContext.reset(new QOpenGLContext()); m_openGlContext->setFormat(window->requestedFormat()); @@ -76,6 +78,9 @@ void QQuickDesignerWindowManager::makeOpenGLContext(QQuickWindow *window) } else { m_openGlContext->makeCurrent(window); } +#else + Q_UNUSED(window) +#endif } void QQuickDesignerWindowManager::exposureChanged(QQuickWindow *) diff --git a/src/quick/designer/qquickdesignerwindowmanager_p.h b/src/quick/designer/qquickdesignerwindowmanager_p.h index 8af54c117f..a50f8aa49f 100644 --- a/src/quick/designer/qquickdesignerwindowmanager_p.h +++ b/src/quick/designer/qquickdesignerwindowmanager_p.h @@ -57,6 +57,10 @@ #include <private/qtquickglobal_p.h> #include <QtQuick/private/qsgcontext_p.h> +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLContext> +#endif + QT_BEGIN_NAMESPACE @@ -64,7 +68,6 @@ class QQuickWindow; class QSGContext; class QSGRenderContext; class QAnimationDriver; -class QOpenGLContext; class QQuickDesignerWindowManager : public QSGRenderLoop { @@ -94,7 +97,9 @@ public: static void createOpenGLContext(QQuickWindow *window); private: +#ifndef QT_NO_OPENGL QScopedPointer<QOpenGLContext> m_openGlContext; +#endif QScopedPointer<QSGContext> m_sgContext; QScopedPointer<QSGRenderContext> m_renderContext; }; diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 68f465cc5a..6603d8158d 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -795,11 +795,13 @@ QSGTextureProvider *QQuickCanvasItem::textureProvider() const return QQuickItem::textureProvider(); Q_D(const QQuickCanvasItem); +#ifndef QT_NO_OPENGL QQuickWindow *w = window(); if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) { qWarning("QQuickCanvasItem::textureProvider: can only be queried on the rendering thread of an exposed window"); return 0; } +#endif if (!d->textureProvider) d->textureProvider = new QQuickCanvasTextureProvider; d->textureProvider->node = d->node; diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 56578b5f16..74666fb8b6 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -72,6 +72,10 @@ #include <private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> +#ifndef QT_NO_OPENGL +# include <private/qsgdefaultrendercontext_p.h> +#endif + #include <cmath> #if defined(Q_OS_QNX) || defined(Q_OS_ANDROID) #include <ctype.h> @@ -3977,10 +3981,12 @@ public: ~QQuickContext2DThreadCleanup() { +#ifndef QT_NO_OPENGL context->makeCurrent(surface); delete texture; context->doneCurrent(); delete context; +#endif surface->deleteLater(); } @@ -4016,6 +4022,7 @@ QQuickContext2D::~QQuickContext2D() delete m_buffer; if (m_renderTarget == QQuickCanvasItem::FramebufferObject) { +#ifndef QT_NO_OPENGL if (m_renderStrategy == QQuickCanvasItem::Immediate && m_glContext) { Q_ASSERT(QThread::currentThread() == m_glContext->thread()); m_glContext->makeCurrent(m_surface.data()); @@ -4036,6 +4043,7 @@ QQuickContext2D::~QQuickContext2D() m_texture->deleteLater(); } } +#endif } else { // Image based does not have GL resources, but must still be deleted // on its designated thread after it has completed whatever it might @@ -4061,8 +4069,6 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args m_canvas = canvasItem; m_renderTarget = canvasItem->renderTarget(); - - QQuickWindow *window = canvasItem->window(); m_renderStrategy = canvasItem->renderStrategy(); #ifdef Q_OS_WIN @@ -4085,9 +4091,12 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args case QQuickCanvasItem::Image: m_texture = new QQuickContext2DImageTexture; break; +#ifndef QT_NO_OPENGL case QQuickCanvasItem::FramebufferObject: + m_texture = new QQuickContext2DFBOTexture; break; +#endif } m_texture->setItem(canvasItem); @@ -4100,18 +4109,26 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args m_thread = QThread::currentThread(); QThread *renderThread = m_thread; +#ifndef QT_NO_OPENGL + QQuickWindow *window = canvasItem->window(); QThread *sceneGraphThread = window->openglContext() ? window->openglContext()->thread() : 0; if (m_renderStrategy == QQuickCanvasItem::Threaded) renderThread = QQuickContext2DRenderThread::instance(qmlEngine(canvasItem)); else if (m_renderStrategy == QQuickCanvasItem::Cooperative) renderThread = sceneGraphThread; +#else + if (m_renderStrategy == QQuickCanvasItem::Threaded) + renderThread = QQuickContext2DRenderThread::instance(qmlEngine(canvasItem)); +#endif + if (renderThread && renderThread != QThread::currentThread()) m_texture->moveToThread(renderThread); - +#ifndef QT_NO_OPENGL if (m_renderTarget == QQuickCanvasItem::FramebufferObject && renderThread != sceneGraphThread) { - QOpenGLContext *cc = QQuickWindowPrivate::get(window)->context->openglContext(); + auto openglRenderContext = static_cast<const QSGDefaultRenderContext *>(QQuickWindowPrivate::get(window)->context); + QOpenGLContext *cc = openglRenderContext->openglContext(); m_surface.reset(new QOffscreenSurface); m_surface->setFormat(window->format()); m_surface->create(); @@ -4122,7 +4139,7 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args m_glContext->moveToThread(renderThread); m_texture->initializeOpenGL(m_glContext, m_surface.data()); } - +#endif connect(m_texture, SIGNAL(textureChanged()), SIGNAL(textureChanged())); reset(); @@ -4169,6 +4186,7 @@ QImage QQuickContext2D::toImage(const QRectF& bounds) flush(); m_texture->grabImage(bounds); } else { +#ifndef QT_NO_OPENGL QQuickWindow *window = m_canvas->window(); QOpenGLContext *ctx = window ? window->openglContext() : 0; if (ctx && ctx->isValid()) { @@ -4184,6 +4202,10 @@ QImage QQuickContext2D::toImage(const QRectF& bounds) qWarning() << "Cannot read pixels from canvas before opengl context is valid"; return QImage(); } +#else + flush(); + m_texture->grabImage(bounds); +#endif } } else if (m_renderStrategy == QQuickCanvasItem::Cooperative) { qWarning() << "Pixel readback is not supported in Cooperative mode, please try Threaded or Immediate mode"; diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp index 58b374e696..8d659040b3 100644 --- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp +++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp @@ -42,9 +42,11 @@ #include <qqml.h> #include <QtCore/QMutex> #include <QtQuick/qsgtexture.h> -#include <QtGui/QOpenGLContext> #include <QtGui/QPaintEngine> -#include <QtGui/private/qopenglpaintengine_p.h> +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLContext> +# include <QtGui/private/qopenglpaintengine_p.h> +#endif #define HAS_SHADOW(offsetX, offsetY, blur, color) (color.isValid() && color.alpha() && (blur || offsetX || offsetY)) diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index f3513f447a..1bf5c333be 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -44,14 +44,15 @@ #include <QtQuick/private/qsgtexture_p.h> #include "qquickcontext2dcommandbuffer_p.h" #include <QOpenGLPaintDevice> - +#ifndef QT_NO_OPENGL #include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObjectFormat> +#endif #include <QtCore/QThread> #include <QtGui/QGuiApplication> QT_BEGIN_NAMESPACE - +#ifndef QT_NO_OPENGL #define QT_MINIMUM_FBO_SIZE 64 static inline int qt_next_power_of_two(int v) @@ -85,10 +86,12 @@ struct GLAcquireContext { } QOpenGLContext *ctx; }; - +#endif QQuickContext2DTexture::QQuickContext2DTexture() : m_context(0) +#ifndef QT_NO_OPENGL , m_gl(0) +#endif , m_surface(0) , m_item(0) , m_canvasWindowChanged(false) @@ -250,9 +253,9 @@ void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb) return; } QQuickContext2D::mutex.unlock(); - +#ifndef QT_NO_OPENGL GLAcquireContext currentContext(m_gl, m_surface); - +#endif if (!m_tiledCanvas) { paintWithoutTiles(ccb); delete ccb; @@ -379,7 +382,7 @@ bool QQuickContext2DTexture::event(QEvent *e) } return QObject::event(e); } - +#ifndef QT_NO_OPENGL static inline QSize npotAdjustedSize(const QSize &size) { static bool checked = false; @@ -646,6 +649,7 @@ void QQuickContext2DFBOTexture::endPainting() m_fbo->bindDefault(); } +#endif QQuickContext2DImageTexture::QQuickContext2DImageTexture() : QQuickContext2DTexture() diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h index edc7283283..ed38382892 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture_p.h +++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h @@ -54,10 +54,10 @@ #include <QtQuick/qsgtexture.h> #include "qquickcanvasitem_p.h" #include "qquickcontext2d_p.h" - -#include <QOpenGLContext> -#include <QOpenGLFramebufferObject> - +#ifndef QT_NO_OPENGL +# include <QOpenGLContext> +# include <QOpenGLFramebufferObject> +#endif #include <QtCore/QMutex> #include <QtCore/QWaitCondition> #include <QtCore/QThread> @@ -121,11 +121,12 @@ public: // Called during sync() on the scene graph thread while GUI is blocked. virtual QSGTexture *textureForNextFrame(QSGTexture *lastFrame, QQuickWindow *window) = 0; bool event(QEvent *e); - +#ifndef QT_NO_OPENGL void initializeOpenGL(QOpenGLContext *gl, QOffscreenSurface *s) { m_gl = gl; m_surface = s; } +#endif Q_SIGNALS: void textureChanged(); @@ -152,8 +153,9 @@ protected: QList<QQuickContext2DTile*> m_tiles; QQuickContext2D *m_context; - +#ifndef QT_NO_OPENGL QOpenGLContext *m_gl; +#endif QSurface *m_surface; QQuickContext2D::State m_state; @@ -174,7 +176,7 @@ protected: uint m_painting : 1; uint m_onCustomThread : 1; // Not GUI and not SGRender }; - +#ifndef QT_NO_OPENGL class QQuickContext2DFBOTexture : public QQuickContext2DTexture { Q_OBJECT @@ -209,7 +211,7 @@ private: GLuint m_displayTextures[2]; int m_displayTexture; }; - +#endif class QSGPlainTexture; class QQuickContext2DImageTexture : public QQuickContext2DTexture { diff --git a/src/quick/items/context2d/qquickcontext2dtile.cpp b/src/quick/items/context2d/qquickcontext2dtile.cpp index a1503762de..95b6c9d961 100644 --- a/src/quick/items/context2d/qquickcontext2dtile.cpp +++ b/src/quick/items/context2d/qquickcontext2dtile.cpp @@ -38,10 +38,11 @@ ****************************************************************************/ #include "qquickcontext2dtile_p.h" - -#include <QOpenGLFramebufferObject> -#include <QOpenGLFramebufferObjectFormat> -#include <QOpenGLPaintDevice> +#ifndef QT_NO_OPENGL +# include <QOpenGLFramebufferObject> +# include <QOpenGLFramebufferObjectFormat> +# include <QOpenGLPaintDevice> +#endif QT_BEGIN_NAMESPACE @@ -96,7 +97,7 @@ QPainter* QQuickContext2DTile::createPainter(bool smooth, bool antialiasing) return 0; } - +#ifndef QT_NO_OPENGL QQuickContext2DFBOTile::QQuickContext2DFBOTile() : QQuickContext2DTile() , m_fbo(0) @@ -146,7 +147,7 @@ void QQuickContext2DFBOTile::setRect(const QRect& r) m_fbo = new QOpenGLFramebufferObject(r.size(), format); } } - +#endif QQuickContext2DImageTile::QQuickContext2DImageTile() : QQuickContext2DTile() diff --git a/src/quick/items/context2d/qquickcontext2dtile_p.h b/src/quick/items/context2d/qquickcontext2dtile_p.h index d9be2023c4..a87202daae 100644 --- a/src/quick/items/context2d/qquickcontext2dtile_p.h +++ b/src/quick/items/context2d/qquickcontext2dtile_p.h @@ -52,8 +52,9 @@ // #include "qquickcontext2d_p.h" -#include <QOpenGLFramebufferObject> - +#ifndef QT_NO_OPENGL +# include <QOpenGLFramebufferObject> +#endif QT_BEGIN_NAMESPACE class QQuickContext2DTexture; @@ -82,7 +83,7 @@ protected: QPainter m_painter; }; - +#ifndef QT_NO_OPENGL class QQuickContext2DFBOTile : public QQuickContext2DTile { public: @@ -99,7 +100,7 @@ private: QOpenGLFramebufferObject *m_fbo; }; - +#endif class QQuickContext2DImageTile : public QQuickContext2DTile { public: diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri index ab966b6ccc..cad63a39c4 100644 --- a/src/quick/items/items.pri +++ b/src/quick/items/items.pri @@ -63,10 +63,6 @@ HEADERS += \ $$PWD/qquickstateoperations_p.h \ $$PWD/qquickimplicitsizeitem_p.h \ $$PWD/qquickimplicitsizeitem_p_p.h \ - $$PWD/qquickspriteengine_p.h \ - $$PWD/qquicksprite_p.h \ - $$PWD/qquickspritesequence_p.h \ - $$PWD/qquickanimatedsprite_p.h \ $$PWD/qquickdrag_p.h \ $$PWD/qquickdroparea_p.h \ $$PWD/qquickmultipointtoucharea_p.h \ @@ -76,11 +72,9 @@ HEADERS += \ $$PWD/qquickscreen_p.h \ $$PWD/qquickwindowattached_p.h \ $$PWD/qquickwindowmodule_p.h \ - $$PWD/qquickframebufferobject.h \ - $$PWD/qquickitemgrabresult.h \ + $$PWD/qquickshadereffectsource_p.h \ $$PWD/qquickrendercontrol.h \ - $$PWD/qquickrendercontrol_p.h \ - $$PWD/qquickopenglinfo_p.h + $$PWD/qquickrendercontrol_p.h SOURCES += \ $$PWD/qquickevents.cpp \ @@ -120,10 +114,6 @@ SOURCES += \ $$PWD/qquickitemanimation.cpp \ $$PWD/qquickstateoperations.cpp \ $$PWD/qquickimplicitsizeitem.cpp \ - $$PWD/qquickspriteengine.cpp \ - $$PWD/qquicksprite.cpp \ - $$PWD/qquickspritesequence.cpp \ - $$PWD/qquickanimatedsprite.cpp \ $$PWD/qquickaccessibleattached.cpp \ $$PWD/qquickdrag.cpp \ $$PWD/qquickdroparea.cpp \ @@ -133,36 +123,49 @@ SOURCES += \ $$PWD/qquickwindowmodule.cpp \ $$PWD/qquickscreen.cpp \ $$PWD/qquickwindowattached.cpp \ - $$PWD/qquickframebufferobject.cpp \ - $$PWD/qquickitemgrabresult.cpp \ - $$PWD/qquickrendercontrol.cpp \ - $$PWD/qquickopenglinfo.cpp - -SOURCES += \ - $$PWD/qquickshadereffect.cpp \ - $$PWD/qquickshadereffectmesh.cpp \ - $$PWD/qquickshadereffectnode.cpp \ $$PWD/qquickshadereffectsource.cpp \ + $$PWD/qquickrendercontrol.cpp -HEADERS += \ - $$PWD/qquickshadereffect_p.h \ - $$PWD/qquickshadereffectmesh_p.h \ - $$PWD/qquickshadereffectnode_p.h \ - $$PWD/qquickshadereffectsource_p.h \ +# Items that depend on OpenGL Renderer +contains(QT_CONFIG, opengl(es1|es2)?) { + SOURCES += \ + $$PWD/qquickopenglinfo.cpp \ + $$PWD/qquickshadereffect.cpp \ + $$PWD/qquickshadereffectmesh.cpp \ + $$PWD/qquickshadereffectnode.cpp \ + $$PWD/qquickframebufferobject.cpp \ + $$PWD/qquickspriteengine.cpp \ + $$PWD/qquicksprite.cpp \ + $$PWD/qquickspritesequence.cpp \ + $$PWD/qquickanimatedsprite.cpp \ + $$PWD/qquickitemgrabresult.cpp + + HEADERS += \ + $$PWD/qquickopenglinfo_p.h \ + $$PWD/qquickspriteengine_p.h \ + $$PWD/qquicksprite_p.h \ + $$PWD/qquickspritesequence_p.h \ + $$PWD/qquickanimatedsprite_p.h \ + $$PWD/qquickshadereffect_p.h \ + $$PWD/qquickshadereffectmesh_p.h \ + $$PWD/qquickshadereffectnode_p.h \ + $$PWD/qquickframebufferobject.h \ + $$PWD/qquickitemgrabresult.h -OTHER_FILES += \ - $$PWD/shaders/sprite.vert \ - $$PWD/shaders/sprite.frag \ - $$PWD/shaders/shadereffect.vert \ - $$PWD/shaders/shadereffect.frag \ - $$PWD/shaders/shadereffectfallback.vert \ - $$PWD/shaders/shadereffectfallback.frag \ - $$PWD/shaders/sprite_core.vert \ - $$PWD/shaders/sprite_core.frag \ - $$PWD/shaders/shadereffect_core.vert \ - $$PWD/shaders/shadereffect_core.frag \ - $$PWD/shaders/shadereffectfallback_core.vert \ - $$PWD/shaders/shadereffectfallback_core.frag + OTHER_FILES += \ + $$PWD/shaders/sprite.vert \ + $$PWD/shaders/sprite.frag \ + $$PWD/shaders/shadereffect.vert \ + $$PWD/shaders/shadereffect.frag \ + $$PWD/shaders/shadereffectfallback.vert \ + $$PWD/shaders/shadereffectfallback.frag \ + $$PWD/shaders/sprite_core.vert \ + $$PWD/shaders/sprite_core.frag \ + $$PWD/shaders/shadereffect_core.vert \ + $$PWD/shaders/shadereffect_core.frag \ + $$PWD/shaders/shadereffectfallback_core.vert \ + $$PWD/shaders/shadereffectfallback_core.frag +} RESOURCES += \ $$PWD/items.qrc diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index c5c17615ee..4fd65fbb01 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -311,10 +311,11 @@ public: bool keepTouchGrab() const; void setKeepTouchGrab(bool); +#ifndef QT_NO_OPENGL // implemented in qquickitemgrabresult.cpp Q_REVISION(2) Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize()); QSharedPointer<QQuickItemGrabResult> grabToImage(const QSize &targetSize = QSize()); - +#endif Q_INVOKABLE virtual bool contains(const QPointF &point) const; QTransform itemTransform(QQuickItem *, bool *) const; diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index da1d430ac2..4404006a88 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -77,7 +77,9 @@ #include <QtCore/qelapsedtimer.h> #include <QtQuick/private/qquickshadereffectsource_p.h> -#include <QtQuick/private/qquickshadereffect_p.h> +#ifndef QT_NO_OPENGL +# include <QtQuick/private/qquickshadereffect_p.h> +#endif QT_BEGIN_NAMESPACE diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp index 6822e4042c..3ff61be241 100644 --- a/src/quick/items/qquickitemgrabresult.cpp +++ b/src/quick/items/qquickitemgrabresult.cpp @@ -48,6 +48,7 @@ #include <private/qquickpixmapcache_p.h> #include <private/qquickitem_p.h> #include <private/qsgcontext_p.h> +#include <private/qsgdefaultrendercontext_p.h> QT_BEGIN_NAMESPACE @@ -239,7 +240,7 @@ void QQuickItemGrabResult::render() return; d->texture->setRect(QRectF(0, d->itemSize.height(), d->itemSize.width(), -d->itemSize.height())); - QSGContext *sg = QSGRenderContext::from(QOpenGLContext::currentContext())->sceneGraphContext(); + QSGContext *sg = QSGDefaultRenderContext::from(QOpenGLContext::currentContext())->sceneGraphContext(); const QSize minSize = sg->minimumFBOSize(); d->texture->setSize(QSize(qMax(minSize.width(), d->textureSize.width()), qMax(minSize.height(), d->textureSize.height()))); diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 23245e4a7b..00837363ab 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -41,7 +41,6 @@ #include "qquickitem.h" #include "qquickitem_p.h" -#include "qquickitemgrabresult.h" #include "qquickevents_p_p.h" #include "qquickrectangle_p.h" #include "qquickfocusscope_p.h" @@ -70,18 +69,21 @@ #include "qquicktranslate_p.h" #include "qquickstateoperations_p.h" #include "qquickitemanimation_p.h" -#include <private/qquickshadereffect_p.h> #include <QtQuick/private/qquickshadereffectsource_p.h> //#include <private/qquickpincharea_p.h> #include <QtQuick/private/qquickcanvasitem_p.h> #include <QtQuick/private/qquickcontext2d_p.h> -#include "qquicksprite_p.h" -#include "qquickspritesequence_p.h" -#include "qquickanimatedsprite_p.h" +#ifndef QT_NO_OPENGL +# include "qquickitemgrabresult.h" +# include <private/qquickshadereffect_p.h> +# include "qquicksprite_p.h" +# include "qquickspritesequence_p.h" +# include "qquickanimatedsprite_p.h" +# include "qquickopenglinfo_p.h" +#endif #include "qquickdrag_p.h" #include "qquickdroparea_p.h" #include "qquickmultipointtoucharea_p.h" -#include "qquickopenglinfo_p.h" #include <private/qqmlmetatype_p.h> #include <QtQuick/private/qquickaccessibleattached_p.h> @@ -178,8 +180,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickTextInput,2>(uri,2,2,"TextInput"); qmlRegisterType<QQuickTextInput,3>(uri,2,4,"TextInput"); qmlRegisterType<QQuickViewSection>(uri,major,minor,"ViewSection"); - +#ifndef QT_NO_OPENGL qmlRegisterType<QQuickItemGrabResult>(); +#endif qmlRegisterType<QQuickItemLayer>(); qmlRegisterType<QQuickAnchors>(); qmlRegisterType<QQuickKeyEvent>(); @@ -207,19 +210,20 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickPinch>(uri,major,minor,"Pinch"); qmlRegisterType<QQuickPinchEvent>(); - qmlRegisterType<QQuickShaderEffect>("QtQuick", 2, 0, "ShaderEffect"); qmlRegisterType<QQuickShaderEffectSource>("QtQuick", 2, 0, "ShaderEffectSource"); +#ifndef QT_NO_OPENGL + qmlRegisterType<QQuickShaderEffect>("QtQuick", 2, 0, "ShaderEffect"); qmlRegisterUncreatableType<QQuickShaderEffectMesh>("QtQuick", 2, 0, "ShaderEffectMesh", QQuickShaderEffectMesh::tr("Cannot create instance of abstract class ShaderEffectMesh.")); qmlRegisterType<QQuickGridMesh>("QtQuick", 2, 0, "GridMesh"); - +#endif qmlRegisterUncreatableType<QQuickPaintedItem>("QtQuick", 2, 0, "PaintedItem", QQuickPaintedItem::tr("Cannot create instance of abstract class PaintedItem")); qmlRegisterType<QQuickCanvasItem>("QtQuick", 2, 0, "Canvas"); - +#ifndef QT_NO_OPENGL qmlRegisterType<QQuickSprite>("QtQuick", 2, 0, "Sprite"); qmlRegisterType<QQuickAnimatedSprite>("QtQuick", 2, 0, "AnimatedSprite"); qmlRegisterType<QQuickSpriteSequence>("QtQuick", 2, 0, "SpriteSequence"); - +#endif qmlRegisterType<QQuickParentChange>(uri, major, minor,"ParentChange"); qmlRegisterType<QQuickAnchorChanges>(uri, major, minor,"AnchorChanges"); qmlRegisterType<QQuickAnchorSet>(); @@ -261,9 +265,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickItem, 2>(uri, 2, 4, "Item"); qmlRegisterType<QQuickListView, 2>(uri, 2, 4, "ListView"); qmlRegisterType<QQuickMouseArea, 1>(uri, 2, 4, "MouseArea"); +#ifndef QT_NO_OPENGL qmlRegisterType<QQuickShaderEffect, 1>(uri, 2, 4, "ShaderEffect"); qmlRegisterUncreatableType<QQuickOpenGLInfo>(uri, 2, 4,"OpenGLInfo", QQuickOpenGLInfo::tr("OpenGLInfo is only available via attached properties")); - +#endif qmlRegisterType<QQuickPinchArea, 1>(uri, 2, 5,"PinchArea"); qmlRegisterType<QQuickImage, 2>(uri, 2, 5,"Image"); qmlRegisterType<QQuickMouseArea, 2>(uri, 2, 5, "MouseArea"); diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp index 707214e8de..e4a20b9787 100644 --- a/src/quick/items/qquickpainteditem.cpp +++ b/src/quick/items/qquickpainteditem.cpp @@ -652,11 +652,13 @@ QSGTextureProvider *QQuickPaintedItem::textureProvider() const return QQuickItem::textureProvider(); Q_D(const QQuickPaintedItem); +#ifndef QT_NO_OPENGL QQuickWindow *w = window(); if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) { qWarning("QQuickPaintedItem::textureProvider: can only be queried on the rendering thread of an exposed window"); return 0; } +#endif if (!d->textureProvider) d->textureProvider = new QQuickPaintedItemTextureProvider(); d->textureProvider->node = d->node; diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index e36df53d38..8ac002ed2c 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -44,7 +44,10 @@ #include <QtCore/QTime> #include <QtQuick/private/qquickanimatorcontroller_p.h> -#include <QtGui/QOpenGLContext> +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLContext> +# include <QtQuick/private/qsgdefaultrendercontext_p.h> +#endif #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> @@ -57,9 +60,9 @@ #include <private/qquickshadereffectnode_p.h> QT_BEGIN_NAMESPACE - +#ifndef QT_NO_OPENGL extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); - +#endif /*! \class QQuickRenderControl @@ -134,7 +137,7 @@ QQuickRenderControlPrivate::QQuickRenderControlPrivate() qAddPostRoutine(cleanup); sg = QSGContext::createDefaultContext(); } - rc = new QSGRenderContext(sg); + rc = sg->createRenderContext(); } void QQuickRenderControlPrivate::cleanup() @@ -213,8 +216,9 @@ void QQuickRenderControl::prepareThread(QThread *targetThread) */ void QQuickRenderControl::initialize(QOpenGLContext *gl) { - Q_D(QQuickRenderControl); + Q_D(QQuickRenderControl); +#ifndef QT_NO_OPENGL if (!d->window) { qWarning("QQuickRenderControl::initialize called with no associated window"); return; @@ -229,9 +233,10 @@ void QQuickRenderControl::initialize(QOpenGLContext *gl) // It cannot be done here since the surface to use may not be the // surface belonging to window. In fact window may not have a native // window/surface at all. - d->rc->initialize(gl); - +#else + Q_UNUSED(gl) +#endif d->initialized = true; } @@ -363,7 +368,11 @@ QImage QQuickRenderControl::grab() return QImage(); render(); +#ifndef QT_NO_OPENGL QImage grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false); +#else + QImage grabContent = d->window->grabWindow(); +#endif return grabContent; } diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index a8cf6155a0..338e4dc3a7 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -45,7 +45,6 @@ #include <QtQuick/private/qsgrenderer_p.h> #include <qsgsimplerectnode.h> -#include "qopenglframebufferobject.h" #include "qmath.h" #include <QtQuick/private/qsgtexture_p.h> #include <QtCore/QRunnable> @@ -680,7 +679,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint m_texture->setDevicePixelRatio(d->window->effectiveDevicePixelRatio()); m_texture->setSize(textureSize); m_texture->setRecursive(m_recursive); - m_texture->setFormat(GLenum(m_format)); + m_texture->setFormat(m_format); m_texture->setHasMipmaps(m_mipmap); m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally); m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically); diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 92b04f4ca7..5d7ed2ad2d 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -93,12 +93,19 @@ public: Repeat }; Q_ENUM(WrapMode) - +#ifndef QT_NO_OPENGL enum Format { Alpha = GL_ALPHA, RGB = GL_RGB, RGBA = GL_RGBA }; +#else + enum Format { + Alpha = 0x1906, + RGB, + RGBA + }; +#endif Q_ENUM(Format) enum TextureMirroring { diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index 60d5e3f6dd..025d5b7b6e 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -390,12 +390,15 @@ QImage QQuickSpriteEngine::assembledImage() m_maxFrames = 0; m_imageStateCount = 0; int maxSize = 0; - +#ifndef QT_NO_OPENGL //If there is no current OpenGL Context if (!QOpenGLContext::currentContext()) return QImage(); QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); +#else + maxSize = 2048; +#endif #ifdef SPRITE_IMAGE_DEBUG qDebug() << "MAX TEXTURE SIZE" << maxSize; #endif diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index cae32dfa49..a932e7a508 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -74,8 +74,10 @@ #include <private/qqmlmemoryprofiler_p.h> #include <private/qqmldebugserviceinterfaces_p.h> #include <private/qqmldebugconnector_p.h> - -#include <private/qopenglvertexarrayobject_p.h> +#ifndef QT_NO_OPENGL +# include <private/qopenglvertexarrayobject_p.h> +# include <private/qsgdefaultrendercontext_p.h> +#endif QT_BEGIN_NAMESPACE @@ -3133,10 +3135,10 @@ void QQuickWindow::maybeUpdate() void QQuickWindow::cleanupSceneGraph() { Q_D(QQuickWindow); - +#ifndef QT_NO_OPENGL delete d->vaoHelper; d->vaoHelper = 0; - +#endif if (!d->renderer) return; @@ -3168,8 +3170,19 @@ void QQuickWindow::setTransientParent_helper(QQuickWindow *window) QOpenGLContext *QQuickWindow::openglContext() const { +#ifndef QT_NO_OPENGL Q_D(const QQuickWindow); - return d->context ? d->context->openglContext() : 0; + if (d->context) { + auto openglRenderContext = static_cast<const QSGDefaultRenderContext *>(d->context); + return openglRenderContext->openglContext(); + } else { + return nullptr; + } + + //return d->context ? d->context->openglContext() : 0; +#else + return nullptr; +#endif } /*! @@ -3285,7 +3298,7 @@ bool QQuickWindow::isSceneGraphInitialized() const The corresponding handler is \c onClosing. */ - +#ifndef QT_NO_OPENGL /*! Sets the render target for this window to be \a fbo. @@ -3314,7 +3327,7 @@ void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo) d->renderTargetSize = QSize(); } } - +#endif /*! \overload @@ -3365,7 +3378,7 @@ QSize QQuickWindow::renderTargetSize() const - +#ifndef QT_NO_OPENGL /*! Returns the render target for this window. @@ -3377,7 +3390,7 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const Q_D(const QQuickWindow); return d->renderTarget; } - +#endif /*! Grabs the contents of the window and returns it as an image. @@ -3394,7 +3407,9 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const QImage QQuickWindow::grabWindow() { Q_D(QQuickWindow); - if (!isVisible() && !d->context->openglContext()) { +#ifndef QT_NO_OPENGL + auto openglRenderContext = static_cast<QSGDefaultRenderContext *>(d->context); + if (!isVisible() && !openglRenderContext->openglContext()) { if (!handle() || !size().isValid()) { qWarning("QQuickWindow::grabWindow: window must be created and have a valid size"); @@ -3420,7 +3435,7 @@ QImage QQuickWindow::grabWindow() return image; } - +#endif if (d->renderControl) return d->renderControl->grab(); else if (d->windowManager) @@ -3740,8 +3755,10 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText */ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, CreateTextureOptions options) const { +#ifndef QT_NO_OPENGL Q_D(const QQuickWindow); - if (d->context && d->context->openglContext()) { + auto openglRenderContext = static_cast<const QSGDefaultRenderContext *>(d->context); + if (openglRenderContext && openglRenderContext->openglContext()) { QSGPlainTexture *texture = new QSGPlainTexture(); texture->setTextureId(id); texture->setHasAlphaChannel(options & TextureHasAlphaChannel); @@ -3749,6 +3766,11 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create texture->setTextureSize(size); return texture; } +#else + Q_UNUSED(id) + Q_UNUSED(size) + Q_UNUSED(options) +#endif return 0; } @@ -3818,7 +3840,7 @@ void QQuickWindow::setDefaultAlphaBuffer(bool useAlpha) { QQuickWindowPrivate::defaultAlphaBuffer = useAlpha; } - +#ifndef QT_NO_OPENGL /*! \since 5.2 @@ -3890,7 +3912,7 @@ void QQuickWindow::resetOpenGLState() QOpenGLFramebufferObject::bindDefault(); } - +#endif /*! \qmlproperty string Window::title diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 1024147bb4..a4060541c0 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -110,16 +110,16 @@ public: bool sendEvent(QQuickItem *, QEvent *); QImage grabWindow(); - +#ifndef QT_NO_OPENGL void setRenderTarget(QOpenGLFramebufferObject *fbo); QOpenGLFramebufferObject *renderTarget() const; - +#endif void setRenderTarget(uint fboId, const QSize &size); uint renderTargetId() const; QSize renderTargetSize() const; - +#ifndef QT_NO_OPENGL void resetOpenGLState(); - +#endif QQmlIncubationController *incubationController() const; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/quick/scenegraph/adaptations/adaptations.pri b/src/quick/scenegraph/adaptations/adaptations.pri new file mode 100644 index 0000000000..a3738d6b82 --- /dev/null +++ b/src/quick/scenegraph/adaptations/adaptations.pri @@ -0,0 +1,2 @@ +include(software/software.pri) +config_d3d12: include(d3d12/d3d12.pri) diff --git a/src/quick/scenegraph/adaptations/d3d12/d3d12.pri b/src/quick/scenegraph/adaptations/d3d12/d3d12.pri new file mode 100644 index 0000000000..1a24f84756 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/d3d12.pri @@ -0,0 +1,40 @@ +SOURCES += \ + $$PWD/qsgd3d12adaptation.cpp \ + $$PWD/qsgd3d12renderloop.cpp \ + $$PWD/qsgd3d12renderer.cpp \ + $$PWD/qsgd3d12context.cpp \ + $$PWD/qsgd3d12rendercontext.cpp \ + $$PWD/qsgd3d12rectanglenode.cpp \ + $$PWD/qsgd3d12material.cpp \ + $$PWD/qsgd3d12builtinmaterials.cpp \ + $$PWD/qsgd3d12texture.cpp \ + $$PWD/qsgd3d12imagenode.cpp \ + $$PWD/qsgd3d12glyphnode.cpp \ + $$PWD/qsgd3d12glyphcache.cpp \ + $$PWD/qsgd3d12layer.cpp + +NO_PCH_SOURCES += \ + $$PWD/qsgd3d12engine.cpp + +HEADERS += \ + $$PWD/qsgd3d12adaptation_p.h \ + $$PWD/qsgd3d12renderloop_p.h \ + $$PWD/qsgd3d12renderer_p.h \ + $$PWD/qsgd3d12context_p.h \ + $$PWD/qsgd3d12rendercontext_p.h \ + $$PWD/qsgd3d12engine_p.h \ + $$PWD/qsgd3d12engine_p_p.h \ + $$PWD/qsgd3d12rectanglenode_p.h \ + $$PWD/qsgd3d12material_p.h \ + $$PWD/qsgd3d12builtinmaterials_p.h \ + $$PWD/qsgd3d12texture_p.h \ + $$PWD/qsgd3d12imagenode_p.h \ + $$PWD/qsgd3d12glyphnode_p.h \ + $$PWD/qsgd3d12glyphcache_p.h \ + $$PWD/qsgd3d12layer_p.h + +LIBS += -ldxgi -ld3d12 + +DEFINES += QSG_D3D12 + +include($$PWD/shaders/shaders.pri) diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp new file mode 100644 index 0000000000..826a1cc5cb --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12adaptation_p.h" +#include "qsgd3d12renderloop_p.h" +#include "qsgd3d12context_p.h" + +QT_BEGIN_NAMESPACE + +QSGD3D12Adaptation::QSGD3D12Adaptation(QObject *parent) + : QSGContextPlugin(parent) +{ +} + +QStringList QSGD3D12Adaptation::keys() const +{ + return QStringList() << QLatin1String("d3d12"); +} + +QSGContext *QSGD3D12Adaptation::create(const QString &) const +{ + if (!contextInstance) + contextInstance = new QSGD3D12Context; + + return contextInstance; +} + +QSGRenderLoop *QSGD3D12Adaptation::createWindowManager() +{ + return new QSGD3D12RenderLoop; +} + +QSGD3D12Context *QSGD3D12Adaptation::contextInstance = nullptr; + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h new file mode 100644 index 0000000000..f3f5d5706e --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12adaptation_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12ADAPTATION_P_H +#define QSGD3D12ADAPTATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgcontextplugin_p.h> + +QT_BEGIN_NAMESPACE + +class QSGD3D12Context; +class QSGContext; +class QSGRenderLoop; + +class QSGD3D12Adaptation : public QSGContextPlugin +{ +public: + QSGD3D12Adaptation(QObject *parent = 0); + + QStringList keys() const override; + QSGContext *create(const QString &key) const override; + QSGRenderLoop *createWindowManager() override; + +private: + static QSGD3D12Context *contextInstance; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12ADAPTATION_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials.cpp new file mode 100644 index 0000000000..ab0c98a8cd --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials.cpp @@ -0,0 +1,655 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12builtinmaterials_p.h" +#include "qsgd3d12rendercontext_p.h" +#include <QQuickWindow> + +#include "vs_vertexcolor.hlslh" +#include "ps_vertexcolor.hlslh" +#include "vs_smoothcolor.hlslh" +#include "ps_smoothcolor.hlslh" +#include "vs_texture.hlslh" +#include "ps_texture.hlslh" +#include "vs_smoothtexture.hlslh" +#include "ps_smoothtexture.hlslh" +#include "vs_textmask.hlslh" +#include "ps_textmask24.hlslh" +#include "ps_textmask32.hlslh" +#include "ps_textmask8.hlslh" +#include "vs_styledtext.hlslh" +#include "ps_styledtext.hlslh" +#include "vs_outlinedtext.hlslh" +#include "ps_outlinedtext.hlslh" + +QT_BEGIN_NAMESPACE + +// NB! In HLSL constant buffer data is packed into 4-byte boundaries and, more +// importantly, it is packed so that it does not cross a 16-byte (float4) +// boundary. Hence the need for padding in some cases. + +QSGMaterialType QSGD3D12VertexColorMaterial::mtype; + +QSGMaterialType *QSGD3D12VertexColorMaterial::type() const +{ + return &QSGD3D12VertexColorMaterial::mtype; +} + +int QSGD3D12VertexColorMaterial::compare(const QSGMaterial *other) const +{ + Q_ASSERT(other && type() == other->type()); + // As the vertex color material has all its state in the vertex attributes + // defined by the geometry, all such materials will be equal. + return 0; +} + +static const int VERTEX_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4 +static const int VERTEX_COLOR_CB_SIZE_1 = sizeof(float); // float +static const int VERTEX_COLOR_CB_SIZE = VERTEX_COLOR_CB_SIZE_0 + VERTEX_COLOR_CB_SIZE_1; + +int QSGD3D12VertexColorMaterial::constantBufferSize() const +{ + return QSGD3D12Engine::alignedConstantBufferSize(VERTEX_COLOR_CB_SIZE); +} + +void QSGD3D12VertexColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) +{ + pipelineState->shaders.vs = g_VS_VertexColor; + pipelineState->shaders.vsSize = sizeof(g_VS_VertexColor); + pipelineState->shaders.ps = g_PS_VertexColor; + pipelineState->shaders.psSize = sizeof(g_PS_VertexColor); +} + +QSGD3D12Material::UpdateResults QSGD3D12VertexColorMaterial::updatePipeline(const RenderState &state, + QSGD3D12PipelineState *, + ExtraState *, + quint8 *constantBuffer) +{ + QSGD3D12Material::UpdateResults r = 0; + quint8 *p = constantBuffer; + + if (state.isMatrixDirty()) { + memcpy(p, state.combinedMatrix().constData(), VERTEX_COLOR_CB_SIZE_0); + r |= UpdatedConstantBuffer; + } + p += VERTEX_COLOR_CB_SIZE_0; + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(p, &opacity, VERTEX_COLOR_CB_SIZE_1); + r |= UpdatedConstantBuffer; + } + + return r; +} + +QSGD3D12SmoothColorMaterial::QSGD3D12SmoothColorMaterial() +{ + setFlag(RequiresFullMatrixExceptTranslate, true); + setFlag(Blending, true); +} + +QSGMaterialType QSGD3D12SmoothColorMaterial::mtype; + +QSGMaterialType *QSGD3D12SmoothColorMaterial::type() const +{ + return &QSGD3D12SmoothColorMaterial::mtype; +} + +int QSGD3D12SmoothColorMaterial::compare(const QSGMaterial *other) const +{ + Q_ASSERT(other && type() == other->type()); + return 0; +} + +static const int SMOOTH_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4 +static const int SMOOTH_COLOR_CB_SIZE_1 = sizeof(float); // float +static const int SMOOTH_COLOR_CB_SIZE_2 = 2 * sizeof(float); // float2 +static const int SMOOTH_COLOR_CB_SIZE = SMOOTH_COLOR_CB_SIZE_0 + SMOOTH_COLOR_CB_SIZE_1 + SMOOTH_COLOR_CB_SIZE_2; + +int QSGD3D12SmoothColorMaterial::constantBufferSize() const +{ + return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_COLOR_CB_SIZE); +} + +void QSGD3D12SmoothColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) +{ + pipelineState->shaders.vs = g_VS_SmoothColor; + pipelineState->shaders.vsSize = sizeof(g_VS_SmoothColor); + pipelineState->shaders.ps = g_PS_SmoothColor; + pipelineState->shaders.psSize = sizeof(g_PS_SmoothColor); +} + +QSGD3D12Material::UpdateResults QSGD3D12SmoothColorMaterial::updatePipeline(const RenderState &state, + QSGD3D12PipelineState *, + ExtraState *, + quint8 *constantBuffer) +{ + QSGD3D12Material::UpdateResults r = 0; + quint8 *p = constantBuffer; + + if (state.isMatrixDirty()) { + memcpy(p, state.combinedMatrix().constData(), SMOOTH_COLOR_CB_SIZE_0); + r |= UpdatedConstantBuffer; + } + p += SMOOTH_COLOR_CB_SIZE_0; + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(p, &opacity, SMOOTH_COLOR_CB_SIZE_1); + r |= UpdatedConstantBuffer; + } + p += SMOOTH_COLOR_CB_SIZE_1; + + if (state.isMatrixDirty()) { + const QRect viewport = state.viewportRect(); + const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() }; + memcpy(p, v, SMOOTH_COLOR_CB_SIZE_2); + r |= UpdatedConstantBuffer; + } + + return r; +} + +QSGMaterialType QSGD3D12TextureMaterial::mtype; + +QSGMaterialType *QSGD3D12TextureMaterial::type() const +{ + return &QSGD3D12TextureMaterial::mtype; +} + +int QSGD3D12TextureMaterial::compare(const QSGMaterial *other) const +{ + Q_ASSERT(other && type() == other->type()); + const QSGD3D12TextureMaterial *o = static_cast<const QSGD3D12TextureMaterial *>(other); + if (int diff = m_texture->textureId() - o->texture()->textureId()) + return diff; + return int(m_filtering) - int(o->m_filtering); +} + +static const int TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4 +static const int TEXTURE_CB_SIZE_1 = sizeof(float); // float +static const int TEXTURE_CB_SIZE = TEXTURE_CB_SIZE_0 + TEXTURE_CB_SIZE_1; + +int QSGD3D12TextureMaterial::constantBufferSize() const +{ + return QSGD3D12Engine::alignedConstantBufferSize(TEXTURE_CB_SIZE); +} + +void QSGD3D12TextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) +{ + pipelineState->shaders.vs = g_VS_Texture; + pipelineState->shaders.vsSize = sizeof(g_VS_Texture); + pipelineState->shaders.ps = g_PS_Texture; + pipelineState->shaders.psSize = sizeof(g_PS_Texture); + + pipelineState->shaders.rootSig.textureViews.resize(1); +} + +QSGD3D12Material::UpdateResults QSGD3D12TextureMaterial::updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *, + quint8 *constantBuffer) +{ + QSGD3D12Material::UpdateResults r = 0; + quint8 *p = constantBuffer; + + if (state.isMatrixDirty()) { + memcpy(p, state.combinedMatrix().constData(), TEXTURE_CB_SIZE_0); + r |= UpdatedConstantBuffer; + } + p += TEXTURE_CB_SIZE_0; + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(p, &opacity, TEXTURE_CB_SIZE_1); + r |= UpdatedConstantBuffer; + } + + Q_ASSERT(m_texture); + m_texture->setFiltering(m_filtering); + m_texture->setMipmapFiltering(m_mipmap_filtering); + m_texture->setHorizontalWrapMode(m_horizontal_wrap); + m_texture->setVerticalWrapMode(m_vertical_wrap); + + QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]); + if (m_filtering == QSGTexture::Linear) + tv.filter = m_mipmap_filtering == QSGTexture::Linear + ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest; + else + tv.filter = m_mipmap_filtering == QSGTexture::Linear + ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest; + tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; + tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; + + m_texture->bind(); + + return r; +} + +QSGD3D12SmoothTextureMaterial::QSGD3D12SmoothTextureMaterial() +{ + setFlag(RequiresFullMatrixExceptTranslate, true); + setFlag(Blending, true); +} + +QSGMaterialType QSGD3D12SmoothTextureMaterial::mtype; + +QSGMaterialType *QSGD3D12SmoothTextureMaterial::type() const +{ + return &QSGD3D12SmoothTextureMaterial::mtype; +} + +int QSGD3D12SmoothTextureMaterial::compare(const QSGMaterial *other) const +{ + Q_ASSERT(other && type() == other->type()); + const QSGD3D12SmoothTextureMaterial *o = static_cast<const QSGD3D12SmoothTextureMaterial *>(other); + if (int diff = m_texture->textureId() - o->texture()->textureId()) + return diff; + return int(m_filtering) - int(o->m_filtering); +} + +static const int SMOOTH_TEXTURE_CB_SIZE_0 = 16 * sizeof(float); // float4x4 +static const int SMOOTH_TEXTURE_CB_SIZE_1 = sizeof(float); // float +static const int SMOOTH_TEXTURE_CB_SIZE_2 = 2 * sizeof(float); // float2 +static const int SMOOTH_TEXTURE_CB_SIZE = SMOOTH_TEXTURE_CB_SIZE_0 + SMOOTH_TEXTURE_CB_SIZE_1 + SMOOTH_TEXTURE_CB_SIZE_2; + +int QSGD3D12SmoothTextureMaterial::constantBufferSize() const +{ + return QSGD3D12Engine::alignedConstantBufferSize(SMOOTH_TEXTURE_CB_SIZE); +} + +void QSGD3D12SmoothTextureMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) +{ + pipelineState->shaders.vs = g_VS_SmoothTexture; + pipelineState->shaders.vsSize = sizeof(g_VS_SmoothTexture); + pipelineState->shaders.ps = g_PS_SmoothTexture; + pipelineState->shaders.psSize = sizeof(g_PS_SmoothTexture); + + pipelineState->shaders.rootSig.textureViews.resize(1); +} + +QSGD3D12Material::UpdateResults QSGD3D12SmoothTextureMaterial::updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *, + quint8 *constantBuffer) +{ + QSGD3D12Material::UpdateResults r = 0; + quint8 *p = constantBuffer; + + if (state.isMatrixDirty()) { + memcpy(p, state.combinedMatrix().constData(), SMOOTH_TEXTURE_CB_SIZE_0); + r |= UpdatedConstantBuffer; + } + p += SMOOTH_TEXTURE_CB_SIZE_0; + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(p, &opacity, SMOOTH_TEXTURE_CB_SIZE_1); + r |= UpdatedConstantBuffer; + } + p += SMOOTH_TEXTURE_CB_SIZE_1; + + if (state.isMatrixDirty()) { + const QRect viewport = state.viewportRect(); + const float v[] = { 2.0f / viewport.width(), 2.0f / viewport.height() }; + memcpy(p, v, SMOOTH_TEXTURE_CB_SIZE_2); + r |= UpdatedConstantBuffer; + } + + Q_ASSERT(m_texture); + m_texture->setFiltering(m_filtering); + m_texture->setMipmapFiltering(m_mipmap_filtering); + m_texture->setHorizontalWrapMode(m_horizontal_wrap); + m_texture->setVerticalWrapMode(m_vertical_wrap); + + QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]); + if (m_filtering == QSGTexture::Linear) + tv.filter = m_mipmap_filtering == QSGTexture::Linear + ? QSGD3D12TextureView::FilterLinear : QSGD3D12TextureView::FilterMinMagLinearMipNearest; + else + tv.filter = m_mipmap_filtering == QSGTexture::Linear + ? QSGD3D12TextureView::FilterMinMagNearestMipLinear : QSGD3D12TextureView::FilterNearest; + tv.addressModeHoriz = m_horizontal_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; + tv.addressModeVert = m_vertical_wrap == QSGTexture::ClampToEdge ? QSGD3D12TextureView::AddressClamp : QSGD3D12TextureView::AddressWrap; + + m_texture->bind(); + + return r; +} + +static inline float qsg_device_pixel_ratio(QSGD3D12Engine *engine) +{ + // ### offscreen render target support will need changes + return engine->windowDevicePixelRatio(); +} + +static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity) +{ + float o = c.w() * globalOpacity; + return QVector4D(c.x() * o, c.y() * o, c.z() * o, o); +} + +static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b) +{ + if (a.x() != b.x()) + return a.x() > b.x() ? 1 : -1; + if (a.y() != b.y()) + return a.y() > b.y() ? 1 : -1; + if (a.z() != b.z()) + return a.z() > b.z() ? 1 : -1; + if (a.w() != b.w()) + return a.w() > b.w() ? 1 : -1; + return 0; +} + +QSGD3D12TextMaterial::QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc, + const QRawFont &font, QFontEngine::GlyphFormat glyphFormat) + : m_styleType(styleType), + m_font(font), + m_rc(rc) +{ + setFlag(Blending, true); + + QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); + if (QFontEngine *fontEngine = fontD->fontEngine) { + if (glyphFormat == QFontEngine::Format_None) + glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None + ? fontEngine->glyphFormat : QFontEngine::Format_A32; + + QSGD3D12Engine *d3dengine = rc->engine(); + const float devicePixelRatio = qsg_device_pixel_ratio(d3dengine); + QTransform glyphCacheTransform = QTransform::fromScale(devicePixelRatio, devicePixelRatio); + if (!fontEngine->supportsTransformation(glyphCacheTransform)) + glyphCacheTransform = QTransform(); + + m_glyphCache = fontEngine->glyphCache(d3dengine, glyphFormat, glyphCacheTransform); + if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) { + m_glyphCache = new QSGD3D12GlyphCache(d3dengine, glyphFormat, glyphCacheTransform); + fontEngine->setGlyphCache(d3dengine, m_glyphCache.data()); + rc->registerFontengineForCleanup(fontEngine); + } + } +} + +QSGMaterialType QSGD3D12TextMaterial::mtype[QSGD3D12TextMaterial::NTextMaterialTypes]; + +QSGMaterialType *QSGD3D12TextMaterial::type() const +{ + // Format_A32 has special blend settings and therefore two materials with + // the same style but different formats where one is A32 are treated as + // different. This way the renderer can manage the pipeline state properly. + const int matStyle = m_styleType * 2; + const int matFormat = glyphCache()->glyphFormat() != QFontEngine::Format_A32 ? 0 : 1; + return &QSGD3D12TextMaterial::mtype[matStyle + matFormat]; +} + +int QSGD3D12TextMaterial::compare(const QSGMaterial *other) const +{ + Q_ASSERT(other && type() == other->type()); + const QSGD3D12TextMaterial *o = static_cast<const QSGD3D12TextMaterial *>(other); + if (m_styleType != o->m_styleType) + return m_styleType - o->m_styleType; + if (m_glyphCache != o->m_glyphCache) + return m_glyphCache.data() < o->m_glyphCache.data() ? -1 : 1; + if (m_styleShift != o->m_styleShift) + return m_styleShift.y() - o->m_styleShift.y(); + int styleColorDiff = qsg_colorDiff(m_styleColor, o->m_styleColor); + if (styleColorDiff) + return styleColorDiff; + return qsg_colorDiff(m_color, o->m_color); +} + +static const int TEXT_CB_SIZE_0 = 16 * sizeof(float); // float4x4 mvp +static const int TEXT_CB_SIZE_1 = 2 * sizeof(float); // float2 textureScale +static const int TEXT_CB_SIZE_2 = sizeof(float); // float dpr +static const int TEXT_CB_SIZE_3 = sizeof(float); // float color +static const int TEXT_CB_SIZE_4 = 4 * sizeof(float); // float4 colorVec +static const int TEXT_CB_SIZE_5 = 2 * sizeof(float); // float2 shift +static const int TEXT_CB_SIZE_5_PADDING = 2 * sizeof(float); // float2 padding (the next float4 would cross the 16-byte boundary) +static const int TEXT_CB_SIZE_6 = 4 * sizeof(float); // float4 styleColor +static const int TEXT_CB_SIZE = TEXT_CB_SIZE_0 + TEXT_CB_SIZE_1 + TEXT_CB_SIZE_2 + TEXT_CB_SIZE_3 + + TEXT_CB_SIZE_4 + TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING + TEXT_CB_SIZE_6; + +int QSGD3D12TextMaterial::constantBufferSize() const +{ + return QSGD3D12Engine::alignedConstantBufferSize(TEXT_CB_SIZE); +} + +void QSGD3D12TextMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) +{ + if (m_styleType == Normal) { + pipelineState->shaders.vs = g_VS_TextMask; + pipelineState->shaders.vsSize = sizeof(g_VS_TextMask); + switch (glyphCache()->glyphFormat()) { + case QFontEngine::Format_A32: + pipelineState->shaders.ps = g_PS_TextMask24; + pipelineState->shaders.psSize = sizeof(g_PS_TextMask24); + break; + case QFontEngine::Format_ARGB: + pipelineState->shaders.ps = g_PS_TextMask32; + pipelineState->shaders.psSize = sizeof(g_PS_TextMask32); + break; + default: + pipelineState->shaders.ps = g_PS_TextMask8; + pipelineState->shaders.psSize = sizeof(g_PS_TextMask8); + break; + } + } else if (m_styleType == Outlined) { + pipelineState->shaders.vs = g_VS_OutlinedText; + pipelineState->shaders.vsSize = sizeof(g_VS_OutlinedText); + pipelineState->shaders.ps = g_PS_OutlinedText; + pipelineState->shaders.psSize = sizeof(g_PS_OutlinedText); + } else { + pipelineState->shaders.vs = g_VS_StyledText; + pipelineState->shaders.vsSize = sizeof(g_VS_StyledText); + pipelineState->shaders.ps = g_PS_StyledText; + pipelineState->shaders.psSize = sizeof(g_PS_StyledText); + } + + pipelineState->shaders.rootSig.textureViews.resize(1); +} + +QSGD3D12Material::UpdateResults QSGD3D12TextMaterial::updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *extraState, + quint8 *constantBuffer) +{ + QSGD3D12Material::UpdateResults r = 0; + quint8 *p = constantBuffer; + + if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) { + // can freely change the state due to the way type() works + pipelineState->blend = QSGD3D12PipelineState::BlendColor; + extraState->blendFactor = m_color; + r |= UpdatedBlendFactor; // must be set always as this affects the command list + } + + if (state.isMatrixDirty()) { + memcpy(p, state.combinedMatrix().constData(), TEXT_CB_SIZE_0); + r |= UpdatedConstantBuffer; + } + p += TEXT_CB_SIZE_0; + + if (state.isCachedMaterialDataDirty() || m_lastGlyphCacheSize != glyphCache()->currentSize()) { + m_lastGlyphCacheSize = glyphCache()->currentSize(); + const float textureScale[2] = { 1.0f / m_lastGlyphCacheSize.width(), + 1.0f / m_lastGlyphCacheSize.height() }; + memcpy(p, textureScale, TEXT_CB_SIZE_1); + r |= UpdatedConstantBuffer; + } + p += TEXT_CB_SIZE_1; + + const float dpr = qsg_device_pixel_ratio(m_rc->engine()); + if (m_lastDpr != dpr) { + m_lastDpr = dpr; + memcpy(p, &dpr, TEXT_CB_SIZE_2); + r |= UpdatedConstantBuffer; + } + p += TEXT_CB_SIZE_2; + + if (state.isOpacityDirty() || m_lastColor != m_color) { + m_lastColor = m_color; + if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) { + const QVector4D color = qsg_premultiply(m_color, state.opacity()); + const float alpha = color.w(); + memcpy(p, &alpha, TEXT_CB_SIZE_3); + } else if (glyphCache()->glyphFormat() == QFontEngine::Format_ARGB) { + const float opacity = m_color.w() * state.opacity(); + memcpy(p, &opacity, TEXT_CB_SIZE_3); + } else { + const QVector4D color = qsg_premultiply(m_color, state.opacity()); + const float f[4] = { color.x(), color.y(), color.z(), color.w() }; + memcpy(p + TEXT_CB_SIZE_3, f, TEXT_CB_SIZE_4); + } + r |= UpdatedConstantBuffer; + } + p += TEXT_CB_SIZE_3 + TEXT_CB_SIZE_4; + + if (m_styleType == Styled && (state.isCachedMaterialDataDirty() || m_lastStyleShift != m_styleShift)) { + m_lastStyleShift = m_styleShift; + const float f[2] = { m_styleShift.x(), m_styleShift.y() }; + memcpy(p, f, TEXT_CB_SIZE_5); + r |= UpdatedConstantBuffer; + } + p += TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING; + + if ((m_styleType == Styled || m_styleType == Outlined) + && (state.isOpacityDirty() || m_lastStyleColor != m_styleColor)) { + m_lastStyleColor = m_styleColor; + const QVector4D color = qsg_premultiply(m_styleColor, state.opacity()); + const float f[4] = { color.x(), color.y(), color.z(), color.w() }; + memcpy(p, f, TEXT_CB_SIZE_6); + r |= UpdatedConstantBuffer; + } + + QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]); + tv.filter = QSGD3D12TextureView::FilterNearest; + tv.addressModeHoriz = QSGD3D12TextureView::AddressClamp; + tv.addressModeVert = QSGD3D12TextureView::AddressClamp; + + glyphCache()->activateTexture(); + + return r; +} + +void QSGD3D12TextMaterial::populate(const QPointF &p, + const QVector<quint32> &glyphIndexes, + const QVector<QPointF> &glyphPositions, + QSGGeometry *geometry, + QRectF *boundingRect, + QPointF *baseLine, + const QMargins &margins) +{ + Q_ASSERT(m_font.isValid()); + QVector<QFixedPoint> fixedPointPositions; + const int glyphPositionsSize = glyphPositions.size(); + fixedPointPositions.reserve(glyphPositionsSize); + for (int i=0; i < glyphPositionsSize; ++i) + fixedPointPositions.append(QFixedPoint::fromPointF(glyphPositions.at(i))); + + QSGD3D12GlyphCache *cache = glyphCache(); + QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); + cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(), + fixedPointPositions.data()); + cache->fillInPendingGlyphs(); + + int margin = fontD->fontEngine->glyphMargin(cache->glyphFormat()); + + float glyphCacheScaleX = cache->transform().m11(); + float glyphCacheScaleY = cache->transform().m22(); + float glyphCacheInverseScaleX = 1.0 / glyphCacheScaleX; + float glyphCacheInverseScaleY = 1.0 / glyphCacheScaleY; + + Q_ASSERT(geometry->indexType() == QSGGeometry::TypeUnsignedShort); + geometry->allocate(glyphIndexes.size() * 4, glyphIndexes.size() * 6); + QVector4D *vp = reinterpret_cast<QVector4D *>(geometry->vertexDataAsTexturedPoint2D()); + Q_ASSERT(geometry->sizeOfVertex() == sizeof(QVector4D)); + ushort *ip = geometry->indexDataAsUShort(); + + QPointF position(p.x(), p.y() - m_font.ascent()); + bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions(); + for (int i = 0; i < glyphIndexes.size(); ++i) { + QFixed subPixelPosition; + if (supportsSubPixelPositions) + subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPositions.at(i).x())); + + QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition); + const QTextureGlyphCache::Coord &c = cache->coords.value(glyph); + + QPointF glyphPosition = glyphPositions.at(i) + position; + float x = (qFloor(glyphPosition.x() * glyphCacheScaleX) * glyphCacheInverseScaleX) + + (c.baseLineX * glyphCacheInverseScaleX) - margin; + float y = (qRound(glyphPosition.y() * glyphCacheScaleY) * glyphCacheInverseScaleY) + - (c.baseLineY * glyphCacheInverseScaleY) - margin; + + float w = c.w * glyphCacheInverseScaleX; + float h = c.h * glyphCacheInverseScaleY; + + *boundingRect |= QRectF(x + margin, y + margin, w, h); + + float cx1 = x - margins.left(); + float cx2 = x + w + margins.right(); + float cy1 = y - margins.top(); + float cy2 = y + h + margins.bottom(); + + float tx1 = c.x - margins.left(); + float tx2 = c.x + c.w + margins.right(); + float ty1 = c.y - margins.top(); + float ty2 = c.y + c.h + margins.bottom(); + + if (baseLine->isNull()) + *baseLine = glyphPosition; + + vp[4 * i + 0] = QVector4D(cx1, cy1, tx1, ty1); + vp[4 * i + 1] = QVector4D(cx2, cy1, tx2, ty1); + vp[4 * i + 2] = QVector4D(cx1, cy2, tx1, ty2); + vp[4 * i + 3] = QVector4D(cx2, cy2, tx2, ty2); + + int o = i * 4; + ip[6 * i + 0] = o + 0; + ip[6 * i + 1] = o + 2; + ip[6 * i + 2] = o + 3; + ip[6 * i + 3] = o + 3; + ip[6 * i + 4] = o + 1; + ip[6 * i + 5] = o + 0; + } +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials_p.h new file mode 100644 index 0000000000..8a475ddb77 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12builtinmaterials_p.h @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12BUILTINMATERIALS_P_H +#define QSGD3D12BUILTINMATERIALS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qsgd3d12material_p.h" +#include "qsgd3d12glyphcache_p.h" +#include <private/qsgtexture_p.h> +#include <QRawFont> + +QT_BEGIN_NAMESPACE + +class QSGD3D12RenderContext; + +class QSGD3D12VertexColorMaterial : public QSGD3D12Material +{ +public: + QSGMaterialType *type() const override; + int compare(const QSGMaterial *other) const override; + + virtual int constantBufferSize() const override; + void preparePipeline(QSGD3D12PipelineState *pipelineState) override; + UpdateResults updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *extraState, + quint8 *constantBuffer) override; + +private: + static QSGMaterialType mtype; +}; + +class QSGD3D12SmoothColorMaterial : public QSGD3D12Material +{ +public: + QSGD3D12SmoothColorMaterial(); + QSGMaterialType *type() const override; + int compare(const QSGMaterial *other) const override; + + virtual int constantBufferSize() const override; + void preparePipeline(QSGD3D12PipelineState *pipelineState) override; + UpdateResults updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *extraState, + quint8 *constantBuffer) override; + +private: + static QSGMaterialType mtype; +}; + +class QSGD3D12TextureMaterial : public QSGD3D12Material +{ +public: + QSGMaterialType *type() const override; + int compare(const QSGMaterial *other) const override; + + virtual int constantBufferSize() const override; + void preparePipeline(QSGD3D12PipelineState *pipelineState) override; + UpdateResults updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *extraState, + quint8 *constantBuffer) override; + + void setTexture(QSGTexture *texture) { m_texture = texture; } + QSGTexture *texture() const { return m_texture; } + + void setMipmapFiltering(QSGTexture::Filtering filter) { m_mipmap_filtering = filter; } + QSGTexture::Filtering mipmapFiltering() const { return m_mipmap_filtering; } + + void setFiltering(QSGTexture::Filtering filter) { m_filtering = filter; } + QSGTexture::Filtering filtering() const { return m_filtering; } + + void setHorizontalWrapMode(QSGTexture::WrapMode hwrap) { m_horizontal_wrap = hwrap; } + QSGTexture::WrapMode horizontalWrapMode() const { return m_horizontal_wrap; } + + void setVerticalWrapMode(QSGTexture::WrapMode vwrap) { m_vertical_wrap = vwrap; } + QSGTexture::WrapMode verticalWrapMode() const { return m_vertical_wrap; } + +private: + static QSGMaterialType mtype; + + QSGTexture *m_texture = nullptr; + QSGTexture::Filtering m_filtering = QSGTexture::Nearest; + QSGTexture::Filtering m_mipmap_filtering = QSGTexture::None; + QSGTexture::WrapMode m_horizontal_wrap = QSGTexture::ClampToEdge; + QSGTexture::WrapMode m_vertical_wrap = QSGTexture::ClampToEdge; +}; + +class QSGD3D12SmoothTextureMaterial : public QSGD3D12Material +{ +public: + QSGD3D12SmoothTextureMaterial(); + + QSGMaterialType *type() const override; + int compare(const QSGMaterial *other) const override; + + virtual int constantBufferSize() const override; + void preparePipeline(QSGD3D12PipelineState *pipelineState) override; + UpdateResults updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *extraState, + quint8 *constantBuffer) override; + + void setTexture(QSGTexture *texture) { m_texture = texture; } + QSGTexture *texture() const { return m_texture; } + + void setMipmapFiltering(QSGTexture::Filtering filter) { m_mipmap_filtering = filter; } + QSGTexture::Filtering mipmapFiltering() const { return m_mipmap_filtering; } + + void setFiltering(QSGTexture::Filtering filter) { m_filtering = filter; } + QSGTexture::Filtering filtering() const { return m_filtering; } + + void setHorizontalWrapMode(QSGTexture::WrapMode hwrap) { m_horizontal_wrap = hwrap; } + QSGTexture::WrapMode horizontalWrapMode() const { return m_horizontal_wrap; } + + void setVerticalWrapMode(QSGTexture::WrapMode vwrap) { m_vertical_wrap = vwrap; } + QSGTexture::WrapMode verticalWrapMode() const { return m_vertical_wrap; } + +private: + static QSGMaterialType mtype; + + QSGTexture *m_texture = nullptr; + QSGTexture::Filtering m_filtering = QSGTexture::Nearest; + QSGTexture::Filtering m_mipmap_filtering = QSGTexture::None; + QSGTexture::WrapMode m_horizontal_wrap = QSGTexture::ClampToEdge; + QSGTexture::WrapMode m_vertical_wrap = QSGTexture::ClampToEdge; +}; + +class QSGD3D12TextMaterial : public QSGD3D12Material +{ +public: + enum StyleType { + Normal, + Styled, + Outlined, + + NStyleTypes + }; + QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc, const QRawFont &font, + QFontEngine::GlyphFormat glyphFormat = QFontEngine::Format_None); + + QSGMaterialType *type() const override; + int compare(const QSGMaterial *other) const override; + + virtual int constantBufferSize() const override; + void preparePipeline(QSGD3D12PipelineState *pipelineState) override; + UpdateResults updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *extraState, + quint8 *constantBuffer) override; + + void setColor(const QColor &c) { m_color = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } + void setColor(const QVector4D &color) { m_color = color; } + const QVector4D &color() const { return m_color; } + + void setStyleShift(const QVector2D &shift) { m_styleShift = shift; } + const QVector2D &styleShift() const { return m_styleShift; } + + void setStyleColor(const QColor &c) { m_styleColor = QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF()); } + void setStyleColor(const QVector4D &color) { m_styleColor = color; } + const QVector4D &styleColor() const { return m_styleColor; } + + void populate(const QPointF &position, + const QVector<quint32> &glyphIndexes, const QVector<QPointF> &glyphPositions, + QSGGeometry *geometry, QRectF *boundingRect, QPointF *baseLine, + const QMargins &margins = QMargins(0, 0, 0, 0)); + + QSGD3D12GlyphCache *glyphCache() const { return static_cast<QSGD3D12GlyphCache *>(m_glyphCache.data()); } + +private: + static const int NTextMaterialTypes = NStyleTypes * 2; + static QSGMaterialType mtype[NTextMaterialTypes]; + StyleType m_styleType; + QSGD3D12RenderContext *m_rc; + QVector4D m_color; + QVector2D m_styleShift; + QVector4D m_styleColor; + QRawFont m_font; + QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache; + QSize m_lastGlyphCacheSize; + float m_lastDpr = 0; + QVector4D m_lastColor; + QVector2D m_lastStyleShift; + QVector4D m_lastStyleColor; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12BUILTINMATERIALS_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp new file mode 100644 index 0000000000..0bb342226b --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12context_p.h" +#include "qsgd3d12rendercontext_p.h" +#include "qsgd3d12rectanglenode_p.h" +#include "qsgd3d12imagenode_p.h" +#include "qsgd3d12glyphnode_p.h" +#include "qsgd3d12layer_p.h" + +QT_BEGIN_NAMESPACE + +QSGRenderContext *QSGD3D12Context::createRenderContext() +{ + return new QSGD3D12RenderContext(this); +} + +QSGRectangleNode *QSGD3D12Context::createRectangleNode() +{ + return new QSGD3D12RectangleNode; +} + +QSGImageNode *QSGD3D12Context::createImageNode() +{ + return new QSGD3D12ImageNode; +} + +QSGPainterNode *QSGD3D12Context::createPainterNode(QQuickPaintedItem *item) +{ + Q_UNUSED(item); + Q_UNREACHABLE(); + return nullptr; +} + +QSGGlyphNode *QSGD3D12Context::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) +{ + Q_UNUSED(preferNativeGlyphNode); + // ### distance field text rendering is not supported atm + + return new QSGD3D12GlyphNode(static_cast<QSGD3D12RenderContext *>(rc)); +} + +QSGNinePatchNode *QSGD3D12Context::createNinePatchNode() +{ + Q_UNREACHABLE(); + return nullptr; +} + +QSGLayer *QSGD3D12Context::createLayer(QSGRenderContext *rc) +{ + return new QSGD3D12Layer(static_cast<QSGD3D12RenderContext *>(rc)); +} + +QSize QSGD3D12Context::minimumFBOSize() const +{ + return QSize(16, 16); +} + +QSurfaceFormat QSGD3D12Context::defaultSurfaceFormat() const +{ + return QSurfaceFormat::defaultFormat(); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h new file mode 100644 index 0000000000..2afe22e3af --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12CONTEXT_P_H +#define QSGD3D12CONTEXT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgcontext_p.h> + +QT_BEGIN_NAMESPACE + +class QSGD3D12Context : public QSGContext +{ +public: + QSGD3D12Context(QObject *parent = 0) : QSGContext(parent) { } + + QSGRenderContext *createRenderContext() override; + QSGRectangleNode *createRectangleNode() override; + QSGImageNode *createImageNode() override; + QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override; + QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override; + QSGNinePatchNode *createNinePatchNode() override; + QSGLayer *createLayer(QSGRenderContext *rc) override; + QSize minimumFBOSize() const override; + QSurfaceFormat defaultSurfaceFormat() const override; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12CONTEXT_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp new file mode 100644 index 0000000000..afeeea760c --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp @@ -0,0 +1,2740 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12engine_p.h" +#include "qsgd3d12engine_p_p.h" +#include "cs_mipmapgen.hlslh" +#include <QString> +#include <QColor> +#include <qmath.h> +#include <QtCore/private/qsimd_p.h> + +QT_BEGIN_NAMESPACE + +// NOTE: Avoid categorized logging. It is slow. + +#define DECLARE_DEBUG_VAR(variable) \ + static bool debug_ ## variable() \ + { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } + +DECLARE_DEBUG_VAR(render) + +static const int DEFAULT_SWAP_CHAIN_BUFFER_COUNT = 3; +static const int DEFAULT_FRAME_IN_FLIGHT_COUNT = 2; +static const int DEFAULT_WAITABLE_SWAP_CHAIN_MAX_LATENCY = 0; + +static const int MAX_DRAW_CALLS_PER_LIST = 128; + +static const int MAX_CACHED_ROOTSIG = 16; +static const int MAX_CACHED_PSO = 64; + +static const int GPU_CBVSRVUAV_DESCRIPTORS = 512; + +static const int BUCKETS_PER_HEAP = 8; // must match freeMap +static const int DESCRIPTORS_PER_BUCKET = 32; // the bit map (freeMap) is quint32 +static const int MAX_DESCRIPTORS_PER_HEAP = BUCKETS_PER_HEAP * DESCRIPTORS_PER_BUCKET; + +D3D12_CPU_DESCRIPTOR_HANDLE QSGD3D12CPUDescriptorHeapManager::allocate(D3D12_DESCRIPTOR_HEAP_TYPE type) +{ + D3D12_CPU_DESCRIPTOR_HANDLE h = {}; + for (Heap &heap : m_heaps) { + if (heap.type == type) { + for (int bucket = 0; bucket < _countof(heap.freeMap); ++bucket) + if (heap.freeMap[bucket]) { + unsigned long freePos = _bit_scan_forward(heap.freeMap[bucket]); + heap.freeMap[bucket] &= ~(1UL << freePos); + if (Q_UNLIKELY(debug_render())) + qDebug("descriptor handle type %x reserve in bucket %d index %d", type, bucket, freePos); + freePos += bucket * DESCRIPTORS_PER_BUCKET; + h = heap.start; + h.ptr += freePos * heap.handleSize; + return h; + } + } + } + + Heap heap; + heap.type = type; + heap.handleSize = m_handleSizes[type]; + + D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; + heapDesc.NumDescriptors = MAX_DESCRIPTORS_PER_HEAP; + heapDesc.Type = type; + // The heaps created here are _never_ shader-visible. + + HRESULT hr = m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&heap.heap)); + if (FAILED(hr)) { + qWarning("Failed to create heap with type 0x%x: %x", type, hr); + return h; + } + + heap.start = heap.heap->GetCPUDescriptorHandleForHeapStart(); + + if (Q_UNLIKELY(debug_render())) + qDebug("new descriptor heap, type %x, start %llu", type, heap.start.ptr); + + heap.freeMap[0] = 0xFFFFFFFE; + for (int i = 1; i < _countof(heap.freeMap); ++i) + heap.freeMap[i] = 0xFFFFFFFF; + + h = heap.start; + + m_heaps.append(heap); + + return h; +} + +void QSGD3D12CPUDescriptorHeapManager::release(D3D12_CPU_DESCRIPTOR_HANDLE handle, D3D12_DESCRIPTOR_HEAP_TYPE type) +{ + for (Heap &heap : m_heaps) { + if (heap.type == type + && handle.ptr >= heap.start.ptr + && handle.ptr < heap.start.ptr + heap.handleSize * MAX_DESCRIPTORS_PER_HEAP) { + unsigned long pos = (handle.ptr - heap.start.ptr) / heap.handleSize; + const int bucket = pos / DESCRIPTORS_PER_BUCKET; + const int indexInBucket = pos - bucket * DESCRIPTORS_PER_BUCKET; + heap.freeMap[bucket] |= 1UL << indexInBucket; + if (Q_UNLIKELY(debug_render())) + qDebug("free descriptor handle type %x bucket %d index %d", type, bucket, indexInBucket); + return; + } + } + qWarning("QSGD3D12CPUDescriptorHeapManager: Attempted to release untracked descriptor handle %llu of type %d", handle.ptr, type); +} + +void QSGD3D12CPUDescriptorHeapManager::initialize(ID3D12Device *device) +{ + m_device = device; + + for (int i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i) + m_handleSizes[i] = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE(i)); +} + +void QSGD3D12CPUDescriptorHeapManager::releaseResources() +{ + for (Heap &heap : m_heaps) + heap.heap = nullptr; + + m_heaps.clear(); + + m_device = nullptr; +} + +// One device per process, one everything else (engine) per window. +Q_GLOBAL_STATIC(QSGD3D12DeviceManager, deviceManager) + +static void getHardwareAdapter(IDXGIFactory1 *factory, IDXGIAdapter1 **outAdapter) +{ + const D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_0; + ComPtr<IDXGIAdapter1> adapter; + DXGI_ADAPTER_DESC1 desc; + + for (int adapterIndex = 0; factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + const QString name = QString::fromUtf16((char16_t *) desc.Description); + qDebug("Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags); + } + + if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX")) { + const int adapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX"); + if (SUCCEEDED(factory->EnumAdapters1(adapterIndex, &adapter)) + && SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr))) { + adapter->GetDesc1(&desc); + const QString name = QString::fromUtf16((char16_t *) desc.Description); + qDebug("Using requested adapter '%s'", qPrintable(name)); + *outAdapter = adapter.Detach(); + return; + } + } + + for (int adapterIndex = 0; factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) { + adapter->GetDesc1(&desc); + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + continue; + + if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr))) { + const QString name = QString::fromUtf16((char16_t *) desc.Description); + qDebug("Using adapter '%s'", qPrintable(name)); + break; + } + } + + *outAdapter = adapter.Detach(); +} + +ID3D12Device *QSGD3D12DeviceManager::ref() +{ + ensureCreated(); + m_ref.ref(); + return m_device.Get(); +} + +void QSGD3D12DeviceManager::unref() +{ + if (!m_ref.deref()) { + if (Q_UNLIKELY(debug_render())) + qDebug("destroying d3d device"); + m_device = nullptr; + m_factory = nullptr; + } +} + +void QSGD3D12DeviceManager::deviceLossDetected() +{ + for (DeviceLossObserver *observer : qAsConst(m_observers)) + observer->deviceLost(); + + // Nothing else to do here. All windows are expected to release their + // resources and call unref() in response immediately. +} + +IDXGIFactory4 *QSGD3D12DeviceManager::dxgi() +{ + ensureCreated(); + return m_factory.Get(); +} + +void QSGD3D12DeviceManager::ensureCreated() +{ + if (m_device) + return; + + HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(&m_factory)); + if (FAILED(hr)) { + qWarning("Failed to create DXGI: 0x%x", hr); + return; + } + + ComPtr<IDXGIAdapter1> adapter; + getHardwareAdapter(m_factory.Get(), &adapter); + + bool warp = true; + if (adapter) { + HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)); + if (SUCCEEDED(hr)) + warp = false; + else + qWarning("Failed to create device: 0x%x", hr); + } + + if (warp) { + qDebug("Using WARP"); + m_factory->EnumWarpAdapter(IID_PPV_ARGS(&adapter)); + HRESULT hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)); + if (FAILED(hr)) { + qWarning("Failed to create WARP device: 0x%x", hr); + return; + } + } + + ComPtr<IDXGIAdapter3> adapter3; + if (SUCCEEDED(adapter.As(&adapter3))) { + DXGI_QUERY_VIDEO_MEMORY_INFO vidMemInfo; + if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &vidMemInfo))) { + qDebug("Video memory info: LOCAL: Budget %llu KB CurrentUsage %llu KB AvailableForReservation %llu KB CurrentReservation %llu KB", + vidMemInfo.Budget / 1024, vidMemInfo.CurrentUsage / 1024, + vidMemInfo.AvailableForReservation / 1024, vidMemInfo.CurrentReservation / 1024); + } + if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &vidMemInfo))) { + qDebug("Video memory info: NON-LOCAL: Budget %llu KB CurrentUsage %llu KB AvailableForReservation %llu KB CurrentReservation %llu KB", + vidMemInfo.Budget / 1024, vidMemInfo.CurrentUsage / 1024, + vidMemInfo.AvailableForReservation / 1024, vidMemInfo.CurrentReservation / 1024); + } + } +} + +void QSGD3D12DeviceManager::registerDeviceLossObserver(DeviceLossObserver *observer) +{ + if (!m_observers.contains(observer)) + m_observers.append(observer); +} + +QSGD3D12Engine::QSGD3D12Engine() +{ + d = new QSGD3D12EnginePrivate; +} + +QSGD3D12Engine::~QSGD3D12Engine() +{ + d->waitGPU(); + d->releaseResources(); + delete d; +} + +bool QSGD3D12Engine::attachToWindow(WId window, const QSize &size, float dpr, int samples) +{ + if (d->isInitialized()) { + qWarning("QSGD3D12Engine: Cannot attach active engine to window"); + return false; + } + + d->initialize(window, size, dpr, samples); + return d->isInitialized(); +} + +void QSGD3D12Engine::releaseResources() +{ + d->releaseResources(); +} + +bool QSGD3D12Engine::hasResources() const +{ + // An explicit releaseResources() or a device loss results in initialized == false. + return d->isInitialized(); +} + +void QSGD3D12Engine::setWindowSize(const QSize &size, float dpr) +{ + d->setWindowSize(size, dpr); +} + +WId QSGD3D12Engine::window() const +{ + return d->currentWindow(); +} + +QSize QSGD3D12Engine::windowSize() const +{ + return d->currentWindowSize(); +} + +float QSGD3D12Engine::windowDevicePixelRatio() const +{ + return d->currentWindowDpr(); +} + +void QSGD3D12Engine::beginFrame() +{ + d->beginFrame(); +} + +void QSGD3D12Engine::endFrame() +{ + d->endFrame(); +} + +void QSGD3D12Engine::beginLayer() +{ + d->beginLayer(); +} + +void QSGD3D12Engine::endLayer() +{ + d->endLayer(); +} + +void QSGD3D12Engine::finalizePipeline(const QSGD3D12PipelineState &pipelineState) +{ + d->finalizePipeline(pipelineState); +} + +uint QSGD3D12Engine::genBuffer() +{ + return d->genBuffer(); +} + +void QSGD3D12Engine::releaseBuffer(uint id) +{ + d->releaseBuffer(id); +} + +void QSGD3D12Engine::resetBuffer(uint id, const quint8 *data, int size) +{ + d->resetBuffer(id, data, size); +} + +void QSGD3D12Engine::markBufferDirty(uint id, int offset, int size) +{ + d->markBufferDirty(id, offset, size); +} + +void QSGD3D12Engine::queueViewport(const QRect &rect) +{ + d->queueViewport(rect); +} + +void QSGD3D12Engine::queueScissor(const QRect &rect) +{ + d->queueScissor(rect); +} + +void QSGD3D12Engine::queueSetRenderTarget(uint id) +{ + d->queueSetRenderTarget(id); +} + +void QSGD3D12Engine::queueClearRenderTarget(const QColor &color) +{ + d->queueClearRenderTarget(color); +} + +void QSGD3D12Engine::queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which) +{ + d->queueClearDepthStencil(depthValue, stencilValue, which); +} + +void QSGD3D12Engine::queueSetBlendFactor(const QVector4D &factor) +{ + d->queueSetBlendFactor(factor); +} + +void QSGD3D12Engine::queueSetStencilRef(quint32 ref) +{ + d->queueSetStencilRef(ref); +} + +void QSGD3D12Engine::queueDraw(const DrawParams ¶ms) +{ + d->queueDraw(params); +} + +void QSGD3D12Engine::present() +{ + d->present(); +} + +void QSGD3D12Engine::waitGPU() +{ + d->waitGPU(); +} + +uint QSGD3D12Engine::genTexture() +{ + return d->genTexture(); +} + +void QSGD3D12Engine::createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags) +{ + d->createTexture(id, size, format, flags); +} + +void QSGD3D12Engine::queueTextureResize(uint id, const QSize &size) +{ + d->queueTextureResize(id, size); +} + +void QSGD3D12Engine::queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos) +{ + d->queueTextureUpload(id, QVector<QImage>() << image, QVector<QPoint>() << dstPos); +} + +void QSGD3D12Engine::queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos) +{ + d->queueTextureUpload(id, images, dstPos); +} + +void QSGD3D12Engine::releaseTexture(uint id) +{ + d->releaseTexture(id); +} + +SIZE_T QSGD3D12Engine::textureSRV(uint id) const +{ + return d->textureSRV(id); +} + +void QSGD3D12Engine::activateTexture(uint id) +{ + d->activateTexture(id); +} + +uint QSGD3D12Engine::genRenderTarget() +{ + return d->genRenderTarget(); +} + +void QSGD3D12Engine::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples) +{ + d->createRenderTarget(id, size, clearColor, samples); +} + +void QSGD3D12Engine::releaseRenderTarget(uint id) +{ + d->releaseRenderTarget(id); +} + +void QSGD3D12Engine::activateRenderTargetAsTexture(uint id) +{ + d->activateRenderTargetAsTexture(id); +} + +static inline quint32 alignedSize(quint32 size, quint32 byteAlign) +{ + return (size + byteAlign - 1) & ~(byteAlign - 1); +} + +quint32 QSGD3D12Engine::alignedConstantBufferSize(quint32 size) +{ + return alignedSize(size, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT); +} + +QSGD3D12Format QSGD3D12Engine::toDXGIFormat(QSGGeometry::Type sgtype, int tupleSize, int *size) +{ + QSGD3D12Format format = FmtUnknown; + + static const QSGD3D12Format formatMap_ub[] = { FmtUnknown, + FmtUNormByte, + FmtUNormByte2, + FmtUnknown, + FmtUNormByte4 }; + + static const QSGD3D12Format formatMap_f[] = { FmtUnknown, + FmtFloat, + FmtFloat2, + FmtFloat3, + FmtFloat4 }; + + switch (sgtype) { + case QSGGeometry::TypeUnsignedByte: + format = formatMap_ub[tupleSize]; + if (size) + *size = tupleSize; + break; + case QSGGeometry::TypeFloat: + format = formatMap_f[tupleSize]; + if (size) + *size = sizeof(float) * tupleSize; + break; + + case QSGGeometry::TypeUnsignedShort: + format = FmtUnsignedShort; + if (size) + *size = sizeof(ushort) * tupleSize; + break; + case QSGGeometry::TypeUnsignedInt: + format = FmtUnsignedInt; + if (size) + *size = sizeof(uint) * tupleSize; + break; + + case QSGGeometry::TypeByte: + case QSGGeometry::TypeInt: + case QSGGeometry::TypeShort: + qWarning("no mapping for GL type 0x%x", sgtype); + break; + + default: + qWarning("unknown GL type 0x%x", sgtype); + break; + } + + return format; +} + +int QSGD3D12Engine::mipMapLevels(const QSize &size) +{ + return ceil(log2(qMax(size.width(), size.height()))) + 1; +} + +inline static bool isPowerOfTwo(int x) +{ + // Assumption: x >= 1 + return x == (x & -x); +} + +QSize QSGD3D12Engine::mipMapAdjustedSourceSize(const QSize &size) +{ + if (size.isEmpty()) + return size; + + QSize adjustedSize = size; + + // ### for now only power-of-two sizes are mipmap-capable + if (!isPowerOfTwo(size.width())) + adjustedSize.setWidth(qNextPowerOfTwo(size.width())); + if (!isPowerOfTwo(size.height())) + adjustedSize.setHeight(qNextPowerOfTwo(size.height())); + + return adjustedSize; +} + +void QSGD3D12EnginePrivate::releaseResources() +{ + if (!initialized) + return; + + mipmapper.releaseResources(); + + frameCommandList = nullptr; + copyCommandList = nullptr; + + copyCommandAllocator = nullptr; + for (int i = 0; i < frameInFlightCount; ++i) { + frameCommandAllocator[i] = nullptr; + pframeData[i].gpuCbvSrvUavHeap = nullptr; + delete frameFence[i]; + } + + defaultDS = nullptr; + for (int i = 0; i < swapChainBufferCount; ++i) { + backBufferRT[i] = nullptr; + defaultRT[i] = nullptr; + } + + psoCache.clear(); + rootSigCache.clear(); + buffers.clear(); + textures.clear(); + renderTargets.clear(); + + cpuDescHeapManager.releaseResources(); + + commandQueue = nullptr; + copyCommandQueue = nullptr; + swapChain = nullptr; + + delete presentFence; + textureUploadFence = nullptr; + + deviceManager()->unref(); + + initialized = false; + + // 'window' must be kept, may just be a device loss +} + +void QSGD3D12EnginePrivate::initialize(WId w, const QSize &size, float dpr, int samples) +{ + if (initialized) + return; + + window = w; + windowSize = size; + windowDpr = dpr; + windowSamples = qMax(1, samples); + + HWND hwnd = reinterpret_cast<HWND>(w); + + swapChainBufferCount = qMin(qEnvironmentVariableIntValue("QT_D3D_BUFFER_COUNT"), MAX_SWAP_CHAIN_BUFFER_COUNT); + if (swapChainBufferCount < 2) + swapChainBufferCount = DEFAULT_SWAP_CHAIN_BUFFER_COUNT; + + frameInFlightCount = qMin(qEnvironmentVariableIntValue("QT_D3D_FRAME_COUNT"), MAX_FRAME_IN_FLIGHT_COUNT); + if (frameInFlightCount < 1) + frameInFlightCount = DEFAULT_FRAME_IN_FLIGHT_COUNT; + + static const char *latReqEnvVar = "QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY"; + if (!qEnvironmentVariableIsSet(latReqEnvVar)) + waitableSwapChainMaxLatency = DEFAULT_WAITABLE_SWAP_CHAIN_MAX_LATENCY; + else + waitableSwapChainMaxLatency = qBound(0, qEnvironmentVariableIntValue(latReqEnvVar), 16); + + qDebug("d3d12 engine init. swap chain buffer count %d, max frames prepared without blocking %d", + swapChainBufferCount, frameInFlightCount); + if (waitableSwapChainMaxLatency) + qDebug("Swap chain frame latency waitable object enabled. Frame latency is %d", waitableSwapChainMaxLatency); + + if (qEnvironmentVariableIntValue("QT_D3D_DEBUG") != 0) { + qDebug("Enabling debug layer"); + ComPtr<ID3D12Debug> debugController; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) + debugController->EnableDebugLayer(); + } + + QSGD3D12DeviceManager *dev = deviceManager(); + device = dev->ref(); + dev->registerDeviceLossObserver(this); + + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + if (FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)))) { + qWarning("Failed to create command queue"); + return; + } + + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY; + if (FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(©CommandQueue)))) { + qWarning("Failed to create copy command queue"); + return; + } + + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferCount = swapChainBufferCount; + swapChainDesc.BufferDesc.Width = windowSize.width() * windowDpr; + swapChainDesc.BufferDesc.Height = windowSize.height() * windowDpr; + swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // D3D12 requires the flip model + swapChainDesc.OutputWindow = hwnd; + swapChainDesc.SampleDesc.Count = 1; // Flip does not support MSAA so no choice here + swapChainDesc.Windowed = TRUE; + if (waitableSwapChainMaxLatency) + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; + + ComPtr<IDXGISwapChain> baseSwapChain; + HRESULT hr = dev->dxgi()->CreateSwapChain(commandQueue.Get(), &swapChainDesc, &baseSwapChain); + if (FAILED(hr)) { + qWarning("Failed to create swap chain: 0x%x", hr); + return; + } + if (FAILED(baseSwapChain.As(&swapChain))) { + qWarning("Failed to cast swap chain"); + return; + } + + dev->dxgi()->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); + + if (waitableSwapChainMaxLatency) { + if (FAILED(swapChain->SetMaximumFrameLatency(waitableSwapChainMaxLatency))) + qWarning("Failed to set maximum frame latency to %d", waitableSwapChainMaxLatency); + swapEvent = swapChain->GetFrameLatencyWaitableObject(); + } + + for (int i = 0; i < frameInFlightCount; ++i) { + if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&frameCommandAllocator[i])))) { + qWarning("Failed to create command allocator"); + return; + } + } + + if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(©CommandAllocator)))) { + qWarning("Failed to create copy command allocator"); + return; + } + + for (int i = 0; i < frameInFlightCount; ++i) { + if (!createCbvSrvUavHeap(i, GPU_CBVSRVUAV_DESCRIPTORS)) + return; + } + + cpuDescHeapManager.initialize(device); + + setupDefaultRenderTargets(); + + if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, frameCommandAllocator[0].Get(), + nullptr, IID_PPV_ARGS(&frameCommandList)))) { + qWarning("Failed to create command list"); + return; + } + // created in recording state, close it for now + frameCommandList->Close(); + + if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, copyCommandAllocator.Get(), + nullptr, IID_PPV_ARGS(©CommandList)))) { + qWarning("Failed to create copy command list"); + return; + } + copyCommandList->Close(); + + frameIndex = 0; + + presentFence = createCPUWaitableFence(); + for (int i = 0; i < frameInFlightCount; ++i) + frameFence[i] = createCPUWaitableFence(); + + if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&textureUploadFence)))) { + qWarning("Failed to create fence"); + return; + } + + psoCache.setMaxCost(MAX_CACHED_PSO); + rootSigCache.setMaxCost(MAX_CACHED_ROOTSIG); + + if (!mipmapper.initialize(this)) + return; + + currentRenderTarget = 0; + + initialized = true; +} + +bool QSGD3D12EnginePrivate::createCbvSrvUavHeap(int pframeIndex, int descriptorCount) +{ + D3D12_DESCRIPTOR_HEAP_DESC gpuDescHeapDesc = {}; + gpuDescHeapDesc.NumDescriptors = descriptorCount; + gpuDescHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + gpuDescHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + + if (FAILED(device->CreateDescriptorHeap(&gpuDescHeapDesc, IID_PPV_ARGS(&pframeData[pframeIndex].gpuCbvSrvUavHeap)))) { + qWarning("Failed to create shader-visible CBV-SRV-UAV heap"); + return false; + } + + pframeData[pframeIndex].gpuCbvSrvUavHeapSize = descriptorCount; + + return true; +} + +DXGI_SAMPLE_DESC QSGD3D12EnginePrivate::makeSampleDesc(DXGI_FORMAT format, int samples) +{ + DXGI_SAMPLE_DESC sampleDesc; + sampleDesc.Count = 1; + sampleDesc.Quality = 0; + + if (samples > 1) { + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaInfo = {}; + msaaInfo.Format = format; + msaaInfo.SampleCount = samples; + if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msaaInfo, sizeof(msaaInfo)))) { + if (msaaInfo.NumQualityLevels > 0) { + sampleDesc.Count = samples; + sampleDesc.Quality = msaaInfo.NumQualityLevels - 1; + } else { + qWarning("No quality levels for multisampling with sample count %d", samples); + } + } else { + qWarning("Failed to query multisample quality levels for sample count %d", samples); + } + } + + return sampleDesc; +} + +ID3D12Resource *QSGD3D12EnginePrivate::createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, + const QVector4D &clearColor, int samples) +{ + D3D12_CLEAR_VALUE clearValue = {}; + clearValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + clearValue.Color[0] = clearColor.x(); + clearValue.Color[1] = clearColor.y(); + clearValue.Color[2] = clearColor.z(); + clearValue.Color[3] = clearColor.w(); + + D3D12_HEAP_PROPERTIES heapProp = {}; + heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; + + D3D12_RESOURCE_DESC rtDesc = {}; + rtDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + rtDesc.Width = size.width(); + rtDesc.Height = size.height(); + rtDesc.DepthOrArraySize = 1; + rtDesc.MipLevels = 1; + rtDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + rtDesc.SampleDesc = makeSampleDesc(rtDesc.Format, samples); + rtDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + + ID3D12Resource *resource = nullptr; + if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &rtDesc, + D3D12_RESOURCE_STATE_RENDER_TARGET, &clearValue, IID_PPV_ARGS(&resource)))) { + qWarning("Failed to create offscreen render target of size %dx%d", size.width(), size.height()); + return nullptr; + } + + device->CreateRenderTargetView(resource, nullptr, viewHandle); + + return resource; +} + +ID3D12Resource *QSGD3D12EnginePrivate::createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, int samples) +{ + D3D12_CLEAR_VALUE depthClearValue = {}; + depthClearValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthClearValue.DepthStencil.Depth = 1.0f; + depthClearValue.DepthStencil.Stencil = 0; + + D3D12_HEAP_PROPERTIES heapProp = {}; + heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; + + D3D12_RESOURCE_DESC bufDesc = {}; + bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + bufDesc.Width = size.width(); + bufDesc.Height = size.height(); + bufDesc.DepthOrArraySize = 1; + bufDesc.MipLevels = 1; + bufDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + bufDesc.SampleDesc = makeSampleDesc(bufDesc.Format, samples); + bufDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + bufDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + + ID3D12Resource *resource = nullptr; + if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, + D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthClearValue, IID_PPV_ARGS(&resource)))) { + qWarning("Failed to create depth-stencil buffer of size %dx%d", size.width(), size.height()); + return nullptr; + } + + D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {}; + depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthStencilDesc.ViewDimension = bufDesc.SampleDesc.Count <= 1 ? D3D12_DSV_DIMENSION_TEXTURE2D : D3D12_DSV_DIMENSION_TEXTURE2DMS; + + device->CreateDepthStencilView(resource, &depthStencilDesc, viewHandle); + + return resource; +} + +void QSGD3D12EnginePrivate::setupDefaultRenderTargets() +{ + for (int i = 0; i < swapChainBufferCount; ++i) { + if (FAILED(swapChain->GetBuffer(i, IID_PPV_ARGS(&backBufferRT[i])))) { + qWarning("Failed to get buffer %d from swap chain", i); + return; + } + defaultRTV[i] = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + if (windowSamples == 1) { + defaultRT[i] = backBufferRT[i]; + device->CreateRenderTargetView(defaultRT[i].Get(), nullptr, defaultRTV[i]); + } else { + const QSize size(windowSize.width() * windowDpr, windowSize.height() * windowDpr); + const QColor cc(Qt::white); // ### what if setClearColor? non-fatal but debug layer warns... + const QVector4D clearColor(cc.redF(), cc.greenF(), cc.blueF(), cc.alphaF()); + ID3D12Resource *msaaRT = createColorBuffer(defaultRTV[i], size, clearColor, windowSamples); + if (msaaRT) + defaultRT[i].Attach(msaaRT); + } + } + + defaultDSV = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + const QSize size(windowSize.width() * windowDpr, windowSize.height() * windowDpr); + ID3D12Resource *ds = createDepthStencil(defaultDSV, size, windowSamples); + if (ds) + defaultDS.Attach(ds); + + presentFrameIndex = 0; +} + +void QSGD3D12EnginePrivate::setWindowSize(const QSize &size, float dpr) +{ + if (!initialized || (windowSize == size && windowDpr == dpr)) + return; + + waitGPU(); + + windowSize = size; + windowDpr = dpr; + + if (Q_UNLIKELY(debug_render())) + qDebug() << "resize" << size << dpr; + + // Clear these, otherwise resizing will fail. + defaultDS = nullptr; + cpuDescHeapManager.release(defaultDSV, D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + for (int i = 0; i < swapChainBufferCount; ++i) { + backBufferRT[i] = nullptr; + defaultRT[i] = nullptr; + cpuDescHeapManager.release(defaultRTV[i], D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + } + + const int w = windowSize.width() * windowDpr; + const int h = windowSize.height() * windowDpr; + HRESULT hr = swapChain->ResizeBuffers(swapChainBufferCount, w, h, DXGI_FORMAT_R8G8B8A8_UNORM, + waitableSwapChainMaxLatency ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0); + if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { + deviceManager()->deviceLossDetected(); + return; + } else if (FAILED(hr)) { + qWarning("Failed to resize buffers: 0x%x", hr); + return; + } + + setupDefaultRenderTargets(); +} + +void QSGD3D12EnginePrivate::deviceLost() +{ + qWarning("D3D device lost, will attempt to reinitialize"); + + // Release all resources. This is important because otherwise reinitialization may fail. + releaseResources(); + + // Now in uninitialized state (but 'window' is still valid). Will recreate + // all the resources on the next beginFrame(). +} + +QSGD3D12CPUWaitableFence *QSGD3D12EnginePrivate::createCPUWaitableFence() const +{ + QSGD3D12CPUWaitableFence *f = new QSGD3D12CPUWaitableFence; + HRESULT hr = device->CreateFence(f->value, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&f->fence)); + if (FAILED(hr)) { + qWarning("Failed to create fence: 0x%x", hr); + return f; + } + f->event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + return f; +} + +void QSGD3D12EnginePrivate::waitForGPU(QSGD3D12CPUWaitableFence *f) const +{ + const UINT64 newValue = f->value.fetchAndAddAcquire(1) + 1; + commandQueue->Signal(f->fence.Get(), newValue); + if (f->fence->GetCompletedValue() < newValue) { + HRESULT hr = f->fence->SetEventOnCompletion(newValue, f->event); + if (FAILED(hr)) { + qWarning("SetEventOnCompletion failed: 0x%x", hr); + return; + } + WaitForSingleObject(f->event, INFINITE); + } +} + +void QSGD3D12EnginePrivate::transitionResource(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList, + D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const +{ + D3D12_RESOURCE_BARRIER barrier; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = resource; + barrier.Transition.StateBefore = before; + barrier.Transition.StateAfter = after; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + commandList->ResourceBarrier(1, &barrier); +} + +void QSGD3D12EnginePrivate::resolveMultisampledTarget(ID3D12Resource *msaa, + ID3D12Resource *resolve, + D3D12_RESOURCE_STATES resolveUsage, + ID3D12GraphicsCommandList *commandList) const +{ + D3D12_RESOURCE_BARRIER barriers[2]; + for (int i = 0; i < _countof(barriers); ++i) { + barriers[i].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barriers[i].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barriers[i].Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + } + + barriers[0].Transition.pResource = msaa; + barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + barriers[1].Transition.pResource = resolve; + barriers[1].Transition.StateBefore = resolveUsage; + barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_DEST; + commandList->ResourceBarrier(2, barriers); + + commandList->ResolveSubresource(resolve, 0, msaa, 0, DXGI_FORMAT_R8G8B8A8_UNORM); + + barriers[0].Transition.pResource = msaa; + barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + barriers[1].Transition.pResource = resolve; + barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_RESOLVE_DEST; + barriers[1].Transition.StateAfter = resolveUsage; + commandList->ResourceBarrier(2, barriers); +} + +void QSGD3D12EnginePrivate::uavBarrier(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList) const +{ + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = resource; + + commandList->ResourceBarrier(1, &barrier); +} + +ID3D12Resource *QSGD3D12EnginePrivate::createBuffer(int size) +{ + ID3D12Resource *buf; + + D3D12_HEAP_PROPERTIES uploadHeapProp = {}; + uploadHeapProp.Type = D3D12_HEAP_TYPE_UPLOAD; + + D3D12_RESOURCE_DESC bufDesc = {}; + bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + bufDesc.Width = size; + bufDesc.Height = 1; + bufDesc.DepthOrArraySize = 1; + bufDesc.MipLevels = 1; + bufDesc.Format = DXGI_FORMAT_UNKNOWN; + bufDesc.SampleDesc.Count = 1; + bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + + HRESULT hr = device->CreateCommittedResource(&uploadHeapProp, D3D12_HEAP_FLAG_NONE, &bufDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&buf)); + if (FAILED(hr)) + qWarning("Failed to create buffer resource: 0x%x", hr); + + return buf; +} + +void QSGD3D12EnginePrivate::ensureBuffer(Buffer *buf) +{ + Buffer::InFlightData &bfd(buf->d[currentPFrameIndex]); + // Only enlarge, never shrink + const bool newBufferNeeded = bfd.buffer ? (buf->cpuDataRef.size > bfd.resourceSize) : true; + if (newBufferNeeded) { + // Round it up and overallocate a little bit so that a subsequent + // buffer contents rebuild with a slightly larger total size does + // not lead to creating a new buffer. + const quint32 sz = alignedSize(buf->cpuDataRef.size, 4096); + if (Q_UNLIKELY(debug_render())) + qDebug("new buffer[pf=%d] of size %d (actual data size %d)", currentPFrameIndex, sz, buf->cpuDataRef.size); + bfd.buffer.Attach(createBuffer(sz)); + bfd.resourceSize = sz; + } + // Cache the actual data size in the per-in-flight-frame data as well. + bfd.dataSize = buf->cpuDataRef.size; +} + +void QSGD3D12EnginePrivate::updateBuffer(Buffer *buf) +{ + if (buf->cpuDataRef.dirty.isEmpty()) + return; + + Buffer::InFlightData &bfd(buf->d[currentPFrameIndex]); + quint8 *p = nullptr; + const D3D12_RANGE readRange = { 0, 0 }; + if (FAILED(bfd.buffer->Map(0, &readRange, reinterpret_cast<void **>(&p)))) { + qWarning("Map failed for buffer of size %d", buf->cpuDataRef.size); + return; + } + for (const auto &r : qAsConst(buf->cpuDataRef.dirty)) { + if (Q_UNLIKELY(debug_render())) + qDebug("%p o %d s %d", buf, r.first, r.second); + memcpy(p + r.first, buf->cpuDataRef.p + r.first, r.second); + } + bfd.buffer->Unmap(0, nullptr); + buf->cpuDataRef.dirty.clear(); +} + +void QSGD3D12EnginePrivate::beginFrame() +{ + if (inFrame && !activeLayers) + qFatal("beginFrame called again without an endFrame, frame index was %d", frameIndex); + + if (Q_UNLIKELY(debug_render())) + qDebug() << "***** begin frame, logical" << frameIndex << "present" << presentFrameIndex << "layer" << activeLayers; + + if (inFrame && activeLayers) { + if (Q_UNLIKELY(debug_render())) + qDebug("frame %d already in progress", frameIndex); + if (!currentLayerDepth) { + // There are layers and the real frame preparation starts now. Prepare for present. + beginFrameDraw(); + } + return; + } + + inFrame = true; + + // The device may have been lost. This is the point to attempt to start again from scratch. + if (!initialized && window) + initialize(window, windowSize, windowDpr, windowSamples); + + // Wait for a buffer to be available for Present, if the waitable event is in use. + if (waitableSwapChainMaxLatency) + WaitForSingleObject(swapEvent, INFINITE); + + // Block if needed. With 2 frames in flight frame N waits for frame N - 2, but not N - 1, to finish. + currentPFrameIndex = frameIndex % frameInFlightCount; + if (frameIndex >= frameInFlightCount) { + ID3D12Fence *fence = frameFence[currentPFrameIndex]->fence.Get(); + HANDLE event = frameFence[currentPFrameIndex]->event; + // Frame fence values start from 1, hence the +1. + const quint64 inFlightFenceValue = frameIndex - frameInFlightCount + 1; + if (fence->GetCompletedValue() < inFlightFenceValue) { + fence->SetEventOnCompletion(inFlightFenceValue, event); + WaitForSingleObject(event, INFINITE); + } + frameCommandAllocator[currentPFrameIndex]->Reset(); + } + + PersistentFrameData &pfd(pframeData[currentPFrameIndex]); + pfd.cbvSrvUavNextFreeDescriptorIndex = 0; + + for (Buffer &b : buffers) { + if (b.entryInUse()) + b.d[currentPFrameIndex].dirty.clear(); + } + + if (frameIndex >= frameInFlightCount) { + // Now sync the buffer changes from the previous, potentially still in + // flight, frames. This is done by taking the ranges dirtied in those + // frames and adding them to the global CPU-side buffer's dirty list, + // as if this frame changed those ranges. (however, dirty ranges + // inherited this way are not added to this frame's persistent + // per-frame dirty list because the next frame after this one should + // inherit this frame's genuine changes only, the rest will come from + // the earlier ones) + for (int delta = frameInFlightCount - 1; delta >= 1; --delta) { + const int prevPFrameIndex = (frameIndex - delta) % frameInFlightCount; + PersistentFrameData &prevFrameData(pframeData[prevPFrameIndex]); + for (uint id : qAsConst(prevFrameData.buffersUsedInFrame)) { + Buffer &b(buffers[id - 1]); + if (b.d[currentPFrameIndex].buffer && b.d[currentPFrameIndex].dataSize == b.cpuDataRef.size) { + if (Q_UNLIKELY(debug_render())) + qDebug() << "frame" << frameIndex << "takes dirty" << b.d[prevPFrameIndex].dirty + << "from frame" << frameIndex - delta << "for buffer" << id; + for (const auto &range : qAsConst(b.d[prevPFrameIndex].dirty)) + addDirtyRange(&b.cpuDataRef.dirty, range.first, range.second, b.cpuDataRef.size); + } else { + if (Q_UNLIKELY(debug_render())) + qDebug() << "frame" << frameIndex << "makes all dirty from frame" << frameIndex - delta + << "for buffer" << id; + addDirtyRange(&b.cpuDataRef.dirty, 0, b.cpuDataRef.size, b.cpuDataRef.size); + } + } + } + + // Do some texture upload bookkeeping. + const quint64 finishedFrameIndex = frameIndex - frameInFlightCount; // we know since we just blocked for this + // pfd conveniently refers to the same slot that was used by that frame + if (!pfd.pendingTextureUploads.isEmpty()) { + if (Q_UNLIKELY(debug_render())) + qDebug("Removing texture upload data for frame %d", finishedFrameIndex); + for (uint id : qAsConst(pfd.pendingTextureUploads)) { + const int idx = id - 1; + Texture &t(textures[idx]); + // fenceValue is 0 when the previous frame cleared it, skip in + // this case. Skip also when fenceValue > the value it was when + // adding the last GPU wait - this is the case when more + // uploads were queued for the same texture in the meantime. + if (t.fenceValue && t.fenceValue == t.lastWaitFenceValue) { + t.fenceValue = 0; + t.lastWaitFenceValue = 0; + t.stagingBuffers.clear(); + t.stagingHeaps.clear(); + if (Q_UNLIKELY(debug_render())) + qDebug("Cleaned staging data for texture %u", id); + } + } + pfd.pendingTextureUploads.clear(); + if (!pfd.pendingTextureMipMap.isEmpty()) { + if (Q_UNLIKELY(debug_render())) + qDebug() << "cleaning mipmap generation data for " << pfd.pendingTextureMipMap; + // no special cleanup is needed as mipmap generation uses the frame's resources + pfd.pendingTextureMipMap.clear(); + } + bool hasPending = false; + for (int delta = 1; delta < frameInFlightCount; ++delta) { + const PersistentFrameData &prevFrameData(pframeData[(frameIndex - delta) % frameInFlightCount]); + if (!prevFrameData.pendingTextureUploads.isEmpty()) { + hasPending = true; + break; + } + } + if (!hasPending) { + if (Q_UNLIKELY(debug_render())) + qDebug("no more pending textures"); + copyCommandAllocator->Reset(); + } + } + + // Do the deferred deletes. + if (!pfd.deleteQueue.isEmpty()) { + for (PersistentFrameData::DeleteQueueEntry &e : pfd.deleteQueue) { + e.res = nullptr; + e.descHeap = nullptr; + if (e.cpuDescriptorPtr) { + D3D12_CPU_DESCRIPTOR_HANDLE h = { e.cpuDescriptorPtr }; + cpuDescHeapManager.release(h, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + } + pfd.deleteQueue.clear(); + } + // Deferred deletes issued outside a begin-endFrame go to the next + // frame's out-of-frame delete queue as these cannot be executed in the + // next beginFrame, only in next + frameInFlightCount. Move to the + // normal queue if this is the next beginFrame. + if (!pfd.outOfFrameDeleteQueue.isEmpty()) { + pfd.deleteQueue = pfd.outOfFrameDeleteQueue; + pfd.outOfFrameDeleteQueue.clear(); + } + + // Mark released texture, buffer, etc. slots free. + if (!pfd.pendingReleases.isEmpty()) { + for (const auto &pr : qAsConst(pfd.pendingReleases)) { + Q_ASSERT(pr.id); + if (pr.type == PersistentFrameData::PendingRelease::TypeTexture) { + Texture &t(textures[pr.id - 1]); + Q_ASSERT(t.entryInUse()); + t.flags &= ~RenderTarget::EntryInUse; // createTexture() can now reuse this entry + t.texture = nullptr; + } else if (pr.type == PersistentFrameData::PendingRelease::TypeBuffer) { + Buffer &b(buffers[pr.id - 1]); + Q_ASSERT(b.entryInUse()); + b.flags &= ~Buffer::EntryInUse; + for (int i = 0; i < frameInFlightCount; ++i) + b.d[i].buffer = nullptr; + } else { + qFatal("Corrupt pending release list, type %d", pr.type); + } + } + pfd.pendingReleases.clear(); + } + if (!pfd.outOfFramePendingReleases.isEmpty()) { + pfd.pendingReleases = pfd.outOfFramePendingReleases; + pfd.outOfFramePendingReleases.clear(); + } + } + + pfd.buffersUsedInFrame.clear(); + + beginDrawCalls(); + + // Prepare for present if this is a frame without layers. + if (!activeLayers) + beginFrameDraw(); +} + +void QSGD3D12EnginePrivate::beginDrawCalls() +{ + frameCommandList->Reset(frameCommandAllocator[frameIndex % frameInFlightCount].Get(), nullptr); + commandList = frameCommandList.Get(); + + tframeData.drawingMode = QSGGeometry::DrawingMode(-1); + tframeData.currentIndexBuffer = 0; + tframeData.drawCount = 0; + tframeData.lastPso = nullptr; + tframeData.lastRootSig = nullptr; + tframeData.descHeapSet = false; +} + +void QSGD3D12EnginePrivate::beginFrameDraw() +{ + if (windowSamples == 1) + transitionResource(defaultRT[presentFrameIndex % swapChainBufferCount].Get(), commandList, + D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); +} + +void QSGD3D12EnginePrivate::endFrame() +{ + if (!inFrame) + qFatal("endFrame called without beginFrame, frame index %d", frameIndex); + + if (Q_UNLIKELY(debug_render())) + qDebug("***** end frame"); + + endDrawCalls(true); + + commandQueue->Signal(frameFence[frameIndex % frameInFlightCount]->fence.Get(), frameIndex + 1); + ++frameIndex; + + inFrame = false; +} + +void QSGD3D12EnginePrivate::endDrawCalls(bool lastInFrame) +{ + PersistentFrameData &pfd(pframeData[currentPFrameIndex]); + + // Now is the time to sync all the changed areas in the buffers. + if (Q_UNLIKELY(debug_render())) + qDebug() << "buffers used in drawcall set" << pfd.buffersUsedInDrawCallSet; + for (uint id : qAsConst(pfd.buffersUsedInDrawCallSet)) + updateBuffer(&buffers[id - 1]); + + pfd.buffersUsedInFrame += pfd.buffersUsedInDrawCallSet; + pfd.buffersUsedInDrawCallSet.clear(); + + // Add a wait on the 3D queue for the relevant texture uploads on the copy queue. + if (!pfd.pendingTextureUploads.isEmpty()) { + quint64 topFenceValue = 0; + for (uint id : qAsConst(pfd.pendingTextureUploads)) { + const int idx = id - 1; + Texture &t(textures[idx]); + Q_ASSERT(t.fenceValue); + // skip if already added a Wait in the previous frame + if (t.lastWaitFenceValue == t.fenceValue) + continue; + t.lastWaitFenceValue = t.fenceValue; + if (t.fenceValue > topFenceValue) + topFenceValue = t.fenceValue; + if (t.mipmap()) + pfd.pendingTextureMipMap.insert(id); + } + if (topFenceValue) { + if (Q_UNLIKELY(debug_render())) + qDebug("added wait for texture fence %llu", topFenceValue); + commandQueue->Wait(textureUploadFence.Get(), topFenceValue); + // Generate mipmaps after the wait, when necessary. + if (!pfd.pendingTextureMipMap.isEmpty()) { + if (Q_UNLIKELY(debug_render())) + qDebug() << "starting mipmap generation for" << pfd.pendingTextureMipMap; + for (uint id : qAsConst(pfd.pendingTextureMipMap)) + mipmapper.queueGenerate(textures[id - 1]); + } + } + } + + if (lastInFrame) { + // Resolve and transition the backbuffer for present, if needed. + const int idx = presentFrameIndex % swapChainBufferCount; + if (windowSamples == 1) { + transitionResource(defaultRT[idx].Get(), commandList, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); + } else { + if (Q_UNLIKELY(debug_render())) { + const D3D12_RESOURCE_DESC desc = defaultRT[idx]->GetDesc(); + qDebug("added resolve for multisampled render target (count %d, quality %d)", + desc.SampleDesc.Count, desc.SampleDesc.Quality); + } + resolveMultisampledTarget(defaultRT[idx].Get(), backBufferRT[idx].Get(), + D3D12_RESOURCE_STATE_PRESENT, commandList); + } + + if (activeLayers) { + if (Q_UNLIKELY(debug_render())) + qDebug("this frame had %d layers", activeLayers); + activeLayers = 0; + } + } + + // Go! + HRESULT hr = frameCommandList->Close(); + if (FAILED(hr)) { + qWarning("Failed to close command list: 0x%x", hr); + if (hr == E_INVALIDARG) + qWarning("Invalid arguments. Some of the commands in the list is invalid in some way."); + } + + ID3D12CommandList *commandLists[] = { frameCommandList.Get() }; + commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists); + + commandList = nullptr; +} + +void QSGD3D12EnginePrivate::beginLayer() +{ + if (inFrame && !activeLayers) + qFatal("Layer rendering cannot be started while a frame is active"); + + if (Q_UNLIKELY(debug_render())) + qDebug("===== beginLayer active %d depth %d (inFrame=%d)", activeLayers, currentLayerDepth, inFrame); + + ++activeLayers; + ++currentLayerDepth; + + // Do an early beginFrame. With multiple layers this results in + // beginLayer - beginFrame - endLayer - beginLayer - beginFrame - endLayer - ... - (*) beginFrame - endFrame + // where (*) denotes the start of the preparation of the actual, non-layer frame. + + if (activeLayers == 1) + beginFrame(); +} + +void QSGD3D12EnginePrivate::endLayer() +{ + if (!inFrame || !activeLayers || !currentLayerDepth) + qFatal("Mismatched endLayer"); + + if (Q_UNLIKELY(debug_render())) + qDebug("===== endLayer active %d depth %d", activeLayers, currentLayerDepth); + + --currentLayerDepth; + + // Do not touch activeLayers. It remains valid until endFrame. +} + +// Root signature: +// [0] CBV - always present +// [1] table with 1 SRV per texture (optional) +// one static sampler per texture (optional) +// +// SRVs can be created freely via QSGD3D12CPUDescriptorHeapManager and stored +// in QSGD3D12TextureView. The engine will copy them onto a dedicated, +// shader-visible CBV-SRV-UAV heap in the correct order. + +void QSGD3D12EnginePrivate::finalizePipeline(const QSGD3D12PipelineState &pipelineState) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + tframeData.pipelineState = pipelineState; + + RootSigCacheEntry *cachedRootSig = rootSigCache[pipelineState.shaders.rootSig]; + if (!cachedRootSig) { + if (Q_UNLIKELY(debug_render())) + qDebug("NEW ROOTSIG"); + + cachedRootSig = new RootSigCacheEntry; + + D3D12_ROOT_PARAMETER rootParams[4]; + int rootParamCount = 0; + + rootParams[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParams[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + rootParams[0].Descriptor.ShaderRegister = 0; // b0 + rootParams[0].Descriptor.RegisterSpace = 0; + ++rootParamCount; + + if (!pipelineState.shaders.rootSig.textureViews.isEmpty()) { + rootParams[rootParamCount].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParams[rootParamCount].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + rootParams[rootParamCount].DescriptorTable.NumDescriptorRanges = 1; + D3D12_DESCRIPTOR_RANGE descRange; + descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + descRange.NumDescriptors = pipelineState.shaders.rootSig.textureViews.count(); + descRange.BaseShaderRegister = 0; // t0, t1, ... + descRange.RegisterSpace = 0; + descRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + rootParams[rootParamCount].DescriptorTable.pDescriptorRanges = &descRange; + ++rootParamCount; + } + + Q_ASSERT(rootParamCount <= _countof(rootParams)); + D3D12_ROOT_SIGNATURE_DESC desc; + desc.NumParameters = rootParamCount; + desc.pParameters = rootParams; + desc.NumStaticSamplers = pipelineState.shaders.rootSig.textureViews.count(); + D3D12_STATIC_SAMPLER_DESC staticSamplers[8]; + int sdIdx = 0; + Q_ASSERT(pipelineState.shaders.rootSig.textureViews.count() <= _countof(staticSamplers)); + for (const QSGD3D12TextureView &tv : qAsConst(pipelineState.shaders.rootSig.textureViews)) { + D3D12_STATIC_SAMPLER_DESC sd = {}; + sd.Filter = D3D12_FILTER(tv.filter); + sd.AddressU = D3D12_TEXTURE_ADDRESS_MODE(tv.addressModeHoriz); + sd.AddressV = D3D12_TEXTURE_ADDRESS_MODE(tv.addressModeVert); + sd.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sd.MinLOD = 0.0f; + sd.MaxLOD = D3D12_FLOAT32_MAX; + sd.ShaderRegister = sdIdx; // t0, t1, ... + sd.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + staticSamplers[sdIdx++] = sd; + } + desc.pStaticSamplers = staticSamplers; + desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + + ComPtr<ID3DBlob> signature; + ComPtr<ID3DBlob> error; + if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) { + qWarning("Failed to serialize root signature"); + return; + } + if (FAILED(device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), + IID_PPV_ARGS(&cachedRootSig->rootSig)))) { + qWarning("Failed to create root signature"); + return; + } + + rootSigCache.insert(pipelineState.shaders.rootSig, cachedRootSig); + } + + PSOCacheEntry *cachedPso = psoCache[pipelineState]; + if (!cachedPso) { + if (Q_UNLIKELY(debug_render())) + qDebug("NEW PSO"); + + cachedPso = new PSOCacheEntry; + + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; + + D3D12_INPUT_ELEMENT_DESC inputElements[8]; + Q_ASSERT(pipelineState.inputElements.count() <= _countof(inputElements)); + int ieIdx = 0; + for (const QSGD3D12InputElement &ie : pipelineState.inputElements) { + D3D12_INPUT_ELEMENT_DESC ieDesc = {}; + ieDesc.SemanticName = ie.semanticName; + ieDesc.SemanticIndex = ie.semanticIndex; + ieDesc.Format = DXGI_FORMAT(ie.format); + ieDesc.InputSlot = ie.slot; + ieDesc.AlignedByteOffset = ie.offset; + ieDesc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; + if (Q_UNLIKELY(debug_render())) + qDebug("input [%d]: %s %d 0x%x %d", ieIdx, ie.semanticName, ie.offset, ie.format, ie.slot); + inputElements[ieIdx++] = ieDesc; + } + + psoDesc.InputLayout = { inputElements, UINT(ieIdx) }; + + psoDesc.pRootSignature = cachedRootSig->rootSig.Get(); + + D3D12_SHADER_BYTECODE vshader; + vshader.pShaderBytecode = pipelineState.shaders.vs; + vshader.BytecodeLength = pipelineState.shaders.vsSize; + D3D12_SHADER_BYTECODE pshader; + pshader.pShaderBytecode = pipelineState.shaders.ps; + pshader.BytecodeLength = pipelineState.shaders.psSize; + + psoDesc.VS = vshader; + psoDesc.PS = pshader; + + D3D12_RASTERIZER_DESC rastDesc = {}; + rastDesc.FillMode = D3D12_FILL_MODE_SOLID; + rastDesc.CullMode = D3D12_CULL_MODE(pipelineState.cullMode); + rastDesc.FrontCounterClockwise = pipelineState.frontCCW; + rastDesc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + rastDesc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + rastDesc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + rastDesc.DepthClipEnable = TRUE; + + psoDesc.RasterizerState = rastDesc; + + D3D12_BLEND_DESC blendDesc = {}; + if (pipelineState.blend == QSGD3D12PipelineState::BlendNone) { + D3D12_RENDER_TARGET_BLEND_DESC noBlendDesc = {}; + noBlendDesc.RenderTargetWriteMask = pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0; + blendDesc.RenderTarget[0] = noBlendDesc; + } else if (pipelineState.blend == QSGD3D12PipelineState::BlendPremul) { + const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = { + TRUE, FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + UINT8(pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0) + }; + blendDesc.RenderTarget[0] = premulBlendDesc; + } else if (pipelineState.blend == QSGD3D12PipelineState::BlendColor) { + const D3D12_RENDER_TARGET_BLEND_DESC colorBlendDesc = { + TRUE, FALSE, + D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_SRC_COLOR, D3D12_BLEND_OP_ADD, + D3D12_BLEND_BLEND_FACTOR, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + UINT8(pipelineState.colorWrite ? D3D12_COLOR_WRITE_ENABLE_ALL : 0) + }; + blendDesc.RenderTarget[0] = colorBlendDesc; + } + psoDesc.BlendState = blendDesc; + + psoDesc.DepthStencilState.DepthEnable = pipelineState.depthEnable; + psoDesc.DepthStencilState.DepthWriteMask = pipelineState.depthWrite ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC(pipelineState.depthFunc); + + psoDesc.DepthStencilState.StencilEnable = pipelineState.stencilEnable; + psoDesc.DepthStencilState.StencilReadMask = psoDesc.DepthStencilState.StencilWriteMask = 0xFF; + D3D12_DEPTH_STENCILOP_DESC stencilOpDesc = { + D3D12_STENCIL_OP(pipelineState.stencilFailOp), + D3D12_STENCIL_OP(pipelineState.stencilDepthFailOp), + D3D12_STENCIL_OP(pipelineState.stencilPassOp), + D3D12_COMPARISON_FUNC(pipelineState.stencilFunc) + }; + psoDesc.DepthStencilState.FrontFace = psoDesc.DepthStencilState.BackFace = stencilOpDesc; + + psoDesc.SampleMask = UINT_MAX; + psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE(pipelineState.topologyType); + psoDesc.NumRenderTargets = 1; + psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; + psoDesc.SampleDesc = defaultRT[0]->GetDesc().SampleDesc; + + HRESULT hr = device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&cachedPso->pso)); + if (FAILED(hr)) { + qWarning("Failed to create graphics pipeline state"); + return; + } + + psoCache.insert(pipelineState, cachedPso); + } + + if (cachedPso->pso.Get() != tframeData.lastPso) { + tframeData.lastPso = cachedPso->pso.Get(); + commandList->SetPipelineState(tframeData.lastPso); + } + + if (cachedRootSig->rootSig.Get() != tframeData.lastRootSig) { + tframeData.lastRootSig = cachedRootSig->rootSig.Get(); + commandList->SetGraphicsRootSignature(tframeData.lastRootSig); + } + + if (!pipelineState.shaders.rootSig.textureViews.isEmpty()) + setDescriptorHeaps(); +} + +void QSGD3D12EnginePrivate::setDescriptorHeaps(bool force) +{ + if (force || !tframeData.descHeapSet) { + tframeData.descHeapSet = true; + ID3D12DescriptorHeap *heaps[] = { pframeData[currentPFrameIndex].gpuCbvSrvUavHeap.Get() }; + commandList->SetDescriptorHeaps(_countof(heaps), heaps); + } +} + +void QSGD3D12EnginePrivate::queueViewport(const QRect &rect) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + tframeData.viewport = rect; + const D3D12_VIEWPORT viewport = { float(rect.x()), float(rect.y()), float(rect.width()), float(rect.height()), 0, 1 }; + commandList->RSSetViewports(1, &viewport); +} + +void QSGD3D12EnginePrivate::queueScissor(const QRect &rect) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + tframeData.scissor = rect; + const D3D12_RECT scissorRect = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() }; + commandList->RSSetScissorRects(1, &scissorRect); +} + +void QSGD3D12EnginePrivate::queueSetRenderTarget(uint id) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle; + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle; + + if (!id) { + rtvHandle = defaultRTV[presentFrameIndex % swapChainBufferCount]; + dsvHandle = defaultDSV; + } else { + const int idx = id - 1; + Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse()); + RenderTarget &rt(renderTargets[idx]); + rtvHandle = rt.rtv; + dsvHandle = rt.dsv; + rt.flags |= RenderTarget::NeedsReadBarrier; + } + + commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle); + + currentRenderTarget = id; +} + +void QSGD3D12EnginePrivate::queueClearRenderTarget(const QColor &color) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + const float clearColor[] = { float(color.redF()), float(color.blueF()), float(color.greenF()), float(color.alphaF()) }; + D3D12_CPU_DESCRIPTOR_HANDLE rtv = !currentRenderTarget + ? defaultRTV[presentFrameIndex % swapChainBufferCount] + : renderTargets[currentRenderTarget - 1].rtv; + commandList->ClearRenderTargetView(rtv, clearColor, 0, nullptr); +} + +void QSGD3D12EnginePrivate::queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + D3D12_CPU_DESCRIPTOR_HANDLE dsv = !currentRenderTarget + ? defaultDSV + : renderTargets[currentRenderTarget - 1].dsv; + commandList->ClearDepthStencilView(dsv, D3D12_CLEAR_FLAGS(int(which)), depthValue, stencilValue, 0, nullptr); +} + +void QSGD3D12EnginePrivate::queueSetBlendFactor(const QVector4D &factor) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + tframeData.blendFactor = factor; + const float f[4] = { factor.x(), factor.y(), factor.z(), factor.w() }; + commandList->OMSetBlendFactor(f); +} + +void QSGD3D12EnginePrivate::queueSetStencilRef(quint32 ref) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + tframeData.stencilRef = ref; + commandList->OMSetStencilRef(ref); +} + +void QSGD3D12EnginePrivate::queueDraw(const QSGD3D12Engine::DrawParams ¶ms) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + const bool skip = tframeData.scissor.isEmpty(); + + PersistentFrameData &pfd(pframeData[currentPFrameIndex]); + + pfd.buffersUsedInDrawCallSet.insert(params.vertexBuf); + const int vertexBufIdx = params.vertexBuf - 1; + Q_ASSERT(params.vertexBuf && vertexBufIdx < buffers.count() && buffers[vertexBufIdx].entryInUse()); + pfd.buffersUsedInDrawCallSet.insert(params.constantBuf); + const int constantBufIdx = params.constantBuf - 1; + Q_ASSERT(params.constantBuf && constantBufIdx < buffers.count() && buffers[constantBufIdx].entryInUse()); + int indexBufIdx = -1; + if (params.indexBuf) { + pfd.buffersUsedInDrawCallSet.insert(params.indexBuf); + indexBufIdx = params.indexBuf - 1; + Q_ASSERT(indexBufIdx < buffers.count() && buffers[indexBufIdx].entryInUse()); + } + + // Ensure buffers are created but do not copy the data here, leave that to endDrawCalls(). + ensureBuffer(&buffers[vertexBufIdx]); + ensureBuffer(&buffers[constantBufIdx]); + if (indexBufIdx >= 0) + ensureBuffer(&buffers[indexBufIdx]); + + // Set the CBV. + if (!skip && params.cboOffset >= 0) { + ID3D12Resource *cbuf = buffers[constantBufIdx].d[currentPFrameIndex].buffer.Get(); + if (cbuf) + commandList->SetGraphicsRootConstantBufferView(0, cbuf->GetGPUVirtualAddress() + params.cboOffset); + } + + // Set up vertex and index buffers. + ID3D12Resource *vbuf = buffers[vertexBufIdx].d[currentPFrameIndex].buffer.Get(); + ID3D12Resource *ibuf = indexBufIdx >= 0 && params.startIndexIndex >= 0 + ? buffers[indexBufIdx].d[currentPFrameIndex].buffer.Get() : nullptr; + + if (!skip && params.mode != tframeData.drawingMode) { + D3D_PRIMITIVE_TOPOLOGY topology; + switch (params.mode) { + case QSGGeometry::DrawPoints: + topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; + break; + case QSGGeometry::DrawLines: + topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; + break; + case QSGGeometry::DrawLineStrip: + topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + break; + case QSGGeometry::DrawTriangles: + topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + break; + case QSGGeometry::DrawTriangleStrip: + topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + break; + default: + qFatal("Unsupported drawing mode 0x%x", params.mode); + break; + } + commandList->IASetPrimitiveTopology(topology); + tframeData.drawingMode = params.mode; + } + + if (!skip) { + D3D12_VERTEX_BUFFER_VIEW vbv; + vbv.BufferLocation = vbuf->GetGPUVirtualAddress() + params.vboOffset; + vbv.SizeInBytes = params.vboSize; + vbv.StrideInBytes = params.vboStride; + + // must be set after the topology + commandList->IASetVertexBuffers(0, 1, &vbv); + } + + if (!skip && params.startIndexIndex >= 0 && ibuf && tframeData.currentIndexBuffer != params.indexBuf) { + tframeData.currentIndexBuffer = params.indexBuf; + D3D12_INDEX_BUFFER_VIEW ibv; + ibv.BufferLocation = ibuf->GetGPUVirtualAddress(); + ibv.SizeInBytes = buffers[indexBufIdx].cpuDataRef.size; + ibv.Format = DXGI_FORMAT(params.indexFormat); + commandList->IASetIndexBuffer(&ibv); + } + + // Copy the SRVs to a drawcall-dedicated area of the shader-visible descriptor heap. + Q_ASSERT(tframeData.activeTextures.count() == tframeData.pipelineState.shaders.rootSig.textureViews.count()); + if (!tframeData.activeTextures.isEmpty()) { + if (!skip) { + ensureGPUDescriptorHeap(tframeData.activeTextures.count()); + const uint stride = cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + D3D12_CPU_DESCRIPTOR_HANDLE dst = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart(); + dst.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride; + for (const TransientFrameData::ActiveTexture &t : qAsConst(tframeData.activeTextures)) { + Q_ASSERT(t.id); + const int idx = t.id - 1; + const bool isTex = t.type == TransientFrameData::ActiveTexture::TypeTexture; + device->CopyDescriptorsSimple(1, dst, isTex ? textures[idx].srv : renderTargets[idx].srv, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + dst.ptr += stride; + } + + D3D12_GPU_DESCRIPTOR_HANDLE gpuAddr = pfd.gpuCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart(); + gpuAddr.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride; + commandList->SetGraphicsRootDescriptorTable(1, gpuAddr); + + pfd.cbvSrvUavNextFreeDescriptorIndex += tframeData.activeTextures.count(); + } + tframeData.activeTextures.clear(); + } + + // Add the draw call. + if (!skip) { + ++tframeData.drawCount; + if (params.startIndexIndex >= 0) + commandList->DrawIndexedInstanced(params.count, 1, params.startIndexIndex, 0, 0); + else + commandList->DrawInstanced(params.count, 1, 0, 0); + } + + if (tframeData.drawCount == MAX_DRAW_CALLS_PER_LIST) { + if (Q_UNLIKELY(debug_render())) + qDebug("Limit of %d draw calls reached, executing command list", MAX_DRAW_CALLS_PER_LIST); + // submit the command list + endDrawCalls(); + // start a new one + beginDrawCalls(); + // prepare for the upcoming drawcalls + queueSetRenderTarget(currentRenderTarget); + queueViewport(tframeData.viewport); + queueScissor(tframeData.scissor); + queueSetBlendFactor(tframeData.blendFactor); + queueSetStencilRef(tframeData.stencilRef); + finalizePipeline(tframeData.pipelineState); + } +} + +void QSGD3D12EnginePrivate::ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount) +{ + PersistentFrameData &pfd(pframeData[currentPFrameIndex]); + int newSize = pfd.gpuCbvSrvUavHeapSize; + while (pfd.cbvSrvUavNextFreeDescriptorIndex + cbvSrvUavDescriptorCount > newSize) + newSize *= 2; + if (newSize != pfd.gpuCbvSrvUavHeapSize) { + if (Q_UNLIKELY(debug_render())) + qDebug("Out of space for SRVs, creating new CBV-SRV-UAV descriptor heap with descriptor count %d", newSize); + deferredDelete(pfd.gpuCbvSrvUavHeap); + createCbvSrvUavHeap(currentPFrameIndex, newSize); + setDescriptorHeaps(true); + pfd.cbvSrvUavNextFreeDescriptorIndex = 0; + } +} + +void QSGD3D12EnginePrivate::present() +{ + if (!initialized) + return; + + if (Q_UNLIKELY(debug_render())) + qDebug("--- present with vsync ---"); + + // This call will not block the CPU unless at least 3 buffers are queued, + // unless the waitable frame latency event is enabled. Then the latency of + // 3 is changed to whatever value desired, and blocking happens in + // beginFrame. If none of these hold, the fence-based wait in beginFrame + // throttles. Vsync (interval 1) is always enabled. + HRESULT hr = swapChain->Present(1, 0); + if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { + deviceManager()->deviceLossDetected(); + return; + } else if (FAILED(hr)) { + qWarning("Present failed: 0x%x", hr); + return; + } + + ++presentFrameIndex; +} + +void QSGD3D12EnginePrivate::waitGPU() +{ + if (!initialized) + return; + + if (Q_UNLIKELY(debug_render())) + qDebug("--- blocking wait for GPU ---"); + + waitForGPU(presentFence); +} + +template<class T> uint newId(T *tbl) +{ + uint id = 0; + for (int i = 0; i < tbl->count(); ++i) { + if (!(*tbl)[i].entryInUse()) { + id = i + 1; + break; + } + } + + if (!id) { + tbl->resize(tbl->size() + 1); + id = tbl->count(); + } + + (*tbl)[id - 1].flags = 0x01; // reset flags and set EntryInUse + + return id; +} + +template<class T> void syncEntryFlags(T *e, int flag, bool b) +{ + if (b) + e->flags |= flag; + else + e->flags &= ~flag; +} + +uint QSGD3D12EnginePrivate::genBuffer() +{ + return newId(&buffers); +} + +void QSGD3D12EnginePrivate::releaseBuffer(uint id) +{ + if (!id) + return; + + const int idx = id - 1; + Q_ASSERT(idx < buffers.count()); + + if (Q_UNLIKELY(debug_render())) + qDebug("releasing buffer %u", id); + + Buffer &b(buffers[idx]); + if (!b.entryInUse()) + return; + + // Do not null out and do not mark the entry reusable yet. + // Do that only when the frames potentially in flight have finished for sure. + + for (int i = 0; i < frameInFlightCount; ++i) { + if (b.d[i].buffer) + deferredDelete(b.d[i].buffer); + } + + QSet<PersistentFrameData::PendingRelease> *pendingReleasesSet = inFrame + ? &pframeData[currentPFrameIndex].pendingReleases + : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFramePendingReleases; + + pendingReleasesSet->insert(PersistentFrameData::PendingRelease(PersistentFrameData::PendingRelease::TypeBuffer, id)); +} + +void QSGD3D12EnginePrivate::resetBuffer(uint id, const quint8 *data, int size) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + Q_ASSERT(id); + const int idx = id - 1; + Q_ASSERT(idx < buffers.count() && buffers[idx].entryInUse()); + Buffer &b(buffers[idx]); + + if (Q_UNLIKELY(debug_render())) + qDebug("reset buffer %u, size %d", id, size); + + b.cpuDataRef.p = data; + b.cpuDataRef.size = size; + + b.cpuDataRef.dirty.clear(); + b.d[currentPFrameIndex].dirty.clear(); + + if (size > 0) { + const QPair<int, int> range = qMakePair(0, size); + b.cpuDataRef.dirty.append(range); + b.d[currentPFrameIndex].dirty.append(range); + } +} + +void QSGD3D12EnginePrivate::addDirtyRange(DirtyList *dirty, int offset, int size, int bufferSize) +{ + // Bail out when the dirty list already spans the entire buffer. + if (!dirty->isEmpty()) { + if (dirty->at(0).first == 0 && dirty->at(0).second == bufferSize) + return; + } + + const QPair<int, int> range = qMakePair(offset, size); + if (!dirty->contains(range)) + dirty->append(range); +} + +void QSGD3D12EnginePrivate::markBufferDirty(uint id, int offset, int size) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + Q_ASSERT(id); + const int idx = id - 1; + Q_ASSERT(idx < buffers.count() && buffers[idx].entryInUse()); + Buffer &b(buffers[idx]); + + addDirtyRange(&b.cpuDataRef.dirty, offset, size, b.cpuDataRef.size); + addDirtyRange(&b.d[currentPFrameIndex].dirty, offset, size, b.cpuDataRef.size); +} + +uint QSGD3D12EnginePrivate::genTexture() +{ + const uint id = newId(&textures); + textures[id - 1].fenceValue = 0; + return id; +} + +static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha, bool mipmap, + QImage::Format *imageFormat, int *bytesPerPixel) +{ + DXGI_FORMAT f = DXGI_FORMAT_R8G8B8A8_UNORM; + QImage::Format convFormat = format; + int bpp = 4; + + if (!mipmap) { + switch (format) { + case QImage::Format_Grayscale8: + case QImage::Format_Indexed8: + case QImage::Format_Alpha8: + f = DXGI_FORMAT_R8_UNORM; + bpp = 1; + break; + case QImage::Format_RGB32: + f = DXGI_FORMAT_B8G8R8A8_UNORM; + break; + case QImage::Format_ARGB32: + f = DXGI_FORMAT_B8G8R8A8_UNORM; + convFormat = wantsAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + break; + case QImage::Format_ARGB32_Premultiplied: + f = DXGI_FORMAT_B8G8R8A8_UNORM; + convFormat = wantsAlpha ? format : QImage::Format_RGB32; + break; + default: + convFormat = wantsAlpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888; + break; + } + } else { + // Mipmap generation needs unordered access and BGRA is not an option for that. Stick to RGBA. + convFormat = wantsAlpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888; + } + + if (imageFormat) + *imageFormat = convFormat; + + if (bytesPerPixel) + *bytesPerPixel = bpp; + + return f; +} + +void QSGD3D12EnginePrivate::createTexture(uint id, const QSize &size, QImage::Format format, + QSGD3D12Engine::TextureCreateFlags createFlags) +{ + Q_ASSERT(id); + const int idx = id - 1; + Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); + Texture &t(textures[idx]); + + syncEntryFlags(&t, Texture::Alpha, createFlags & QSGD3D12Engine::CreateWithAlpha); + syncEntryFlags(&t, Texture::MipMap, createFlags & QSGD3D12Engine::CreateWithMipMaps); + + const QSize adjustedSize = !t.mipmap() ? size : QSGD3D12Engine::mipMapAdjustedSourceSize(size); + + D3D12_HEAP_PROPERTIES defaultHeapProp = {}; + defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT; + + D3D12_RESOURCE_DESC textureDesc = {}; + textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + textureDesc.Width = adjustedSize.width(); + textureDesc.Height = adjustedSize.height(); + textureDesc.DepthOrArraySize = 1; + textureDesc.MipLevels = !t.mipmap() ? 1 : QSGD3D12Engine::mipMapLevels(adjustedSize); + textureDesc.Format = textureFormat(format, t.alpha(), t.mipmap(), nullptr, nullptr); + textureDesc.SampleDesc.Count = 1; + textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + if (t.mipmap()) + textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc, + D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&t.texture)); + if (FAILED(hr)) { + qWarning("Failed to create texture resource: 0x%x", hr); + return; + } + + t.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.Format = textureDesc.Format; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = textureDesc.MipLevels; + + device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv); + + if (t.mipmap()) { + // Mipmap generation will need an UAV for each level that needs to be generated. + t.mipUAVs.clear(); + for (int level = 1; level < textureDesc.MipLevels; ++level) { + D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; + uavDesc.Format = textureDesc.Format; + uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; + uavDesc.Texture2D.MipSlice = level; + D3D12_CPU_DESCRIPTOR_HANDLE h = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + device->CreateUnorderedAccessView(t.texture.Get(), nullptr, &uavDesc, h); + t.mipUAVs.append(h); + } + } + + if (Q_UNLIKELY(debug_render())) + qDebug("created texture %u, size %dx%d, miplevels %d", id, adjustedSize.width(), adjustedSize.height(), textureDesc.MipLevels); +} + +void QSGD3D12EnginePrivate::queueTextureResize(uint id, const QSize &size) +{ + Q_ASSERT(id); + const int idx = id - 1; + Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); + Texture &t(textures[idx]); + + if (!t.texture) { + qWarning("Cannot resize non-created texture %u", id); + return; + } + + if (t.mipmap()) { + qWarning("Cannot resize mipmapped texture %u", id); + return; + } + + if (Q_UNLIKELY(debug_render())) + qDebug("resizing texture %u, size %dx%d", id, size.width(), size.height()); + + D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc(); + textureDesc.Width = size.width(); + textureDesc.Height = size.height(); + + D3D12_HEAP_PROPERTIES defaultHeapProp = {}; + defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT; + + ComPtr<ID3D12Resource> oldTexture = t.texture; + deferredDelete(t.texture); + + HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc, + D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&t.texture)); + if (FAILED(hr)) { + qWarning("Failed to create resized texture resource: 0x%x", hr); + return; + } + + deferredDelete(t.srv); + t.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.Format = textureDesc.Format; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = textureDesc.MipLevels; + + device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv); + + D3D12_TEXTURE_COPY_LOCATION dstLoc; + dstLoc.pResource = t.texture.Get(); + dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLoc.SubresourceIndex = 0; + + D3D12_TEXTURE_COPY_LOCATION srcLoc; + srcLoc.pResource = oldTexture.Get(); + srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + srcLoc.SubresourceIndex = 0; + + copyCommandList->Reset(copyCommandAllocator.Get(), nullptr); + + copyCommandList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr); + + copyCommandList->Close(); + ID3D12CommandList *commandLists[] = { copyCommandList.Get() }; + copyCommandQueue->ExecuteCommandLists(_countof(commandLists), commandLists); + + t.fenceValue = nextTextureUploadFenceValue.fetchAndAddAcquire(1) + 1; + copyCommandQueue->Signal(textureUploadFence.Get(), t.fenceValue); + + if (Q_UNLIKELY(debug_render())) + qDebug("submitted old content copy for texture %u on the copy queue, fence %llu", id, t.fenceValue); +} + +void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos) +{ + Q_ASSERT(id); + Q_ASSERT(images.count() == dstPos.count()); + if (images.isEmpty()) + return; + + const int idx = id - 1; + Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); + Texture &t(textures[idx]); + Q_ASSERT(t.texture); + + // When mipmapping is not in use, image can be smaller than the size passed + // to createTexture() and dstPos can specify a non-zero destination position. + + if (t.mipmap() && (images.count() != 1 || dstPos.count() != 1 || !dstPos[0].isNull())) { + qWarning("Mipmapped textures (%u) do not support partial uploads", id); + return; + } + + // Make life simpler by disallowing queuing a new mipmapped upload before the previous one finishes. + if (t.mipmap() && t.fenceValue) { + qWarning("Attempted to queue mipmapped texture upload (%u) while a previous upload is still in progress", id); + return; + } + + t.fenceValue = nextTextureUploadFenceValue.fetchAndAddAcquire(1) + 1; + + if (Q_UNLIKELY(debug_render())) + qDebug("adding upload for texture %u on the copy queue, fence %llu", id, t.fenceValue); + + D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc(); + const QSize adjustedTextureSize(textureDesc.Width, textureDesc.Height); + + int totalSize = 0; + for (const QImage &image : images) { + int bytesPerPixel; + textureFormat(image.format(), t.alpha(), t.mipmap(), nullptr, &bytesPerPixel); + const int w = !t.mipmap() ? image.width() : adjustedTextureSize.width(); + const int h = !t.mipmap() ? image.height() : adjustedTextureSize.height(); + const int stride = alignedSize(w * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + totalSize += alignedSize(h * stride, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); + } + + if (Q_UNLIKELY(debug_render())) + qDebug("%d sub-uploads, heap size %d bytes", images.count(), totalSize); + + // Instead of individual committed resources for each upload buffer, + // allocate only once and use placed resources. + D3D12_HEAP_PROPERTIES uploadHeapProp = {}; + uploadHeapProp.Type = D3D12_HEAP_TYPE_UPLOAD; + D3D12_HEAP_DESC uploadHeapDesc = {}; + uploadHeapDesc.SizeInBytes = totalSize; + uploadHeapDesc.Properties = uploadHeapProp; + uploadHeapDesc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS; + + Texture::StagingHeap sheap; + if (FAILED(device->CreateHeap(&uploadHeapDesc, IID_PPV_ARGS(&sheap.heap)))) { + qWarning("Failed to create texture upload heap of size %d", totalSize); + return; + } + t.stagingHeaps.append(sheap); + + copyCommandList->Reset(copyCommandAllocator.Get(), nullptr); + + int placedOffset = 0; + for (int i = 0; i < images.count(); ++i) { + QImage::Format convFormat; + int bytesPerPixel; + textureFormat(images[i].format(), t.alpha(), t.mipmap(), &convFormat, &bytesPerPixel); + if (Q_UNLIKELY(debug_render() && i == 0)) + qDebug("source image format %d, target format %d, bpp %d", images[i].format(), convFormat, bytesPerPixel); + + QImage convImage = images[i].format() == convFormat ? images[i] : images[i].convertToFormat(convFormat); + + if (t.mipmap() && adjustedTextureSize != convImage.size()) + convImage = convImage.scaled(adjustedTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + + const int stride = alignedSize(convImage.width() * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + + D3D12_RESOURCE_DESC bufDesc = {}; + bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + bufDesc.Width = stride * convImage.height(); + bufDesc.Height = 1; + bufDesc.DepthOrArraySize = 1; + bufDesc.MipLevels = 1; + bufDesc.Format = DXGI_FORMAT_UNKNOWN; + bufDesc.SampleDesc.Count = 1; + bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + + Texture::StagingBuffer sbuf; + if (FAILED(device->CreatePlacedResource(sheap.heap.Get(), placedOffset, + &bufDesc, D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, IID_PPV_ARGS(&sbuf.buffer)))) { + qWarning("Failed to create texture upload buffer"); + return; + } + + quint8 *p = nullptr; + const D3D12_RANGE readRange = { 0, 0 }; + if (FAILED(sbuf.buffer->Map(0, &readRange, reinterpret_cast<void **>(&p)))) { + qWarning("Map failed (texture upload buffer)"); + return; + } + for (int y = 0, ye = convImage.height(); y < ye; ++y) { + memcpy(p, convImage.constScanLine(y), convImage.width() * bytesPerPixel); + p += stride; + } + sbuf.buffer->Unmap(0, nullptr); + + D3D12_TEXTURE_COPY_LOCATION dstLoc; + dstLoc.pResource = t.texture.Get(); + dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLoc.SubresourceIndex = 0; + + D3D12_TEXTURE_COPY_LOCATION srcLoc; + srcLoc.pResource = sbuf.buffer.Get(); + srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + srcLoc.PlacedFootprint.Offset = 0; + srcLoc.PlacedFootprint.Footprint.Format = textureDesc.Format; + srcLoc.PlacedFootprint.Footprint.Width = convImage.width(); + srcLoc.PlacedFootprint.Footprint.Height = convImage.height(); + srcLoc.PlacedFootprint.Footprint.Depth = 1; + srcLoc.PlacedFootprint.Footprint.RowPitch = stride; + + copyCommandList->CopyTextureRegion(&dstLoc, dstPos[i].x(), dstPos[i].y(), 0, &srcLoc, nullptr); + + t.stagingBuffers.append(sbuf); + placedOffset += alignedSize(bufDesc.Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); + } + + copyCommandList->Close(); + ID3D12CommandList *commandLists[] = { copyCommandList.Get() }; + copyCommandQueue->ExecuteCommandLists(_countof(commandLists), commandLists); + copyCommandQueue->Signal(textureUploadFence.Get(), t.fenceValue); +} + +void QSGD3D12EnginePrivate::releaseTexture(uint id) +{ + if (!id) + return; + + const int idx = id - 1; + Q_ASSERT(idx < textures.count()); + + if (Q_UNLIKELY(debug_render())) + qDebug("releasing texture %d", id); + + Texture &t(textures[idx]); + if (!t.entryInUse()) + return; + + if (t.texture) { + deferredDelete(t.texture); + deferredDelete(t.srv); + for (D3D12_CPU_DESCRIPTOR_HANDLE h : t.mipUAVs) + deferredDelete(h); + } + + QSet<PersistentFrameData::PendingRelease> *pendingReleasesSet = inFrame + ? &pframeData[currentPFrameIndex].pendingReleases + : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFramePendingReleases; + + pendingReleasesSet->insert(PersistentFrameData::PendingRelease(PersistentFrameData::PendingRelease::TypeTexture, id)); +} + +SIZE_T QSGD3D12EnginePrivate::textureSRV(uint id) const +{ + Q_ASSERT(id); + const int idx = id - 1; + Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); + return textures[idx].srv.ptr; +} + +void QSGD3D12EnginePrivate::activateTexture(uint id) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + Q_ASSERT(id); + const int idx = id - 1; + Q_ASSERT(idx < textures.count() && textures[idx].entryInUse()); + + // activeTextures is a vector because the order matters + tframeData.activeTextures.append(TransientFrameData::ActiveTexture(TransientFrameData::ActiveTexture::TypeTexture, id)); + + if (textures[idx].fenceValue) + pframeData[currentPFrameIndex].pendingTextureUploads.insert(id); +} + +bool QSGD3D12EnginePrivate::MipMapGen::initialize(QSGD3D12EnginePrivate *enginePriv) +{ + engine = enginePriv; + + D3D12_STATIC_SAMPLER_DESC sampler = {}; + sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampler.MinLOD = 0.0f; + sampler.MaxLOD = D3D12_FLOAT32_MAX; + + D3D12_DESCRIPTOR_RANGE descRange[2]; + descRange[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + descRange[0].NumDescriptors = 1; + descRange[0].BaseShaderRegister = 0; // t0 + descRange[0].RegisterSpace = 0; + descRange[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + descRange[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + descRange[1].NumDescriptors = 4; + descRange[1].BaseShaderRegister = 0; // u0..u3 + descRange[1].RegisterSpace = 0; + descRange[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + + // Split into two to allow switching between the first and second set of UAVs later. + D3D12_ROOT_PARAMETER rootParameters[3]; + rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + rootParameters[0].DescriptorTable.NumDescriptorRanges = 1; + rootParameters[0].DescriptorTable.pDescriptorRanges = &descRange[0]; + + rootParameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + rootParameters[1].DescriptorTable.NumDescriptorRanges = 1; + rootParameters[1].DescriptorTable.pDescriptorRanges = &descRange[1]; + + rootParameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + rootParameters[2].Constants.Num32BitValues = 4; // uint2 mip1Size, uint sampleLevel, uint totalMips + rootParameters[2].Constants.ShaderRegister = 0; // b0 + rootParameters[2].Constants.RegisterSpace = 0; + + D3D12_ROOT_SIGNATURE_DESC desc = {}; + desc.NumParameters = 3; + desc.pParameters = rootParameters; + desc.NumStaticSamplers = 1; + desc.pStaticSamplers = &sampler; + + ComPtr<ID3DBlob> signature; + ComPtr<ID3DBlob> error; + if (FAILED(D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error))) { + QByteArray msg(static_cast<const char *>(error->GetBufferPointer()), error->GetBufferSize()); + qWarning("Failed to serialize compute root signature: %s", qPrintable(msg)); + return false; + } + if (FAILED(engine->device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), + IID_PPV_ARGS(&rootSig)))) { + qWarning("Failed to create compute root signature"); + return false; + } + + D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {}; + psoDesc.pRootSignature = rootSig.Get(); + psoDesc.CS.pShaderBytecode = g_CS_Generate4MipMaps; + psoDesc.CS.BytecodeLength = sizeof(g_CS_Generate4MipMaps); + + if (FAILED(engine->device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&pipelineState)))) { + qWarning("Failed to create compute pipeline state"); + return false; + } + + return true; +} + +void QSGD3D12EnginePrivate::MipMapGen::releaseResources() +{ + pipelineState = nullptr; + rootSig = nullptr; +} + +// The mipmap generator is used to insert commands on the main 3D queue. It is +// guaranteed that the queue has a wait for the base texture level upload +// before invoking queueGenerate(). There can be any number of invocations +// without waiting for earlier ones to finish. finished() is invoked when it is +// known for sure that frame containing the upload and mipmap generation has +// finished on the GPU. + +void QSGD3D12EnginePrivate::MipMapGen::queueGenerate(const Texture &t) +{ + D3D12_RESOURCE_DESC textureDesc = t.texture->GetDesc(); + + engine->commandList->SetPipelineState(pipelineState.Get()); + engine->commandList->SetComputeRootSignature(rootSig.Get()); + + // 1 SRV + (miplevels - 1) UAVs + const int descriptorCount = 1 + (textureDesc.MipLevels - 1); + + engine->ensureGPUDescriptorHeap(descriptorCount); + + // The descriptor heap is set on the command list either because the + // ensure() call above resized, or, typically, due to a texture-dependent + // draw call earlier. + + engine->transitionResource(t.texture.Get(), engine->commandList, + D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + QSGD3D12EnginePrivate::PersistentFrameData &pfd(engine->pframeData[engine->currentPFrameIndex]); + + const uint stride = engine->cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + D3D12_CPU_DESCRIPTOR_HANDLE h = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart(); + h.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride; + + engine->device->CopyDescriptorsSimple(1, h, t.srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + h.ptr += stride; + + for (int level = 1; level < textureDesc.MipLevels; ++level, h.ptr += stride) + engine->device->CopyDescriptorsSimple(1, h, t.mipUAVs[level - 1], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + D3D12_GPU_DESCRIPTOR_HANDLE gpuAddr = pfd.gpuCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart(); + gpuAddr.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride; + + engine->commandList->SetComputeRootDescriptorTable(0, gpuAddr); + gpuAddr.ptr += stride; // now points to the first UAV + + for (int level = 1; level < textureDesc.MipLevels; level += 4, gpuAddr.ptr += stride * 4) { + engine->commandList->SetComputeRootDescriptorTable(1, gpuAddr); + + QSize sz(textureDesc.Width, textureDesc.Height); + sz.setWidth(qMax(1, sz.width() >> level)); + sz.setHeight(qMax(1, sz.height() >> level)); + + const quint32 constants[4] = { quint32(sz.width()), quint32(sz.height()), + quint32(level - 1), + quint32(textureDesc.MipLevels - 1) }; + + engine->commandList->SetComputeRoot32BitConstants(2, 4, constants, 0); + engine->commandList->Dispatch(sz.width(), sz.height(), 1); + engine->uavBarrier(t.texture.Get(), engine->commandList); + } + + engine->transitionResource(t.texture.Get(), engine->commandList, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + + pfd.cbvSrvUavNextFreeDescriptorIndex += descriptorCount; +} + +void QSGD3D12EnginePrivate::deferredDelete(ComPtr<ID3D12Resource> res) +{ + PersistentFrameData::DeleteQueueEntry e; + e.res = res; + QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame + ? &pframeData[currentPFrameIndex].deleteQueue + : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue; + (*dq) << e; +} + +void QSGD3D12EnginePrivate::deferredDelete(ComPtr<ID3D12DescriptorHeap> dh) +{ + PersistentFrameData::DeleteQueueEntry e; + e.descHeap = dh; + QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame + ? &pframeData[currentPFrameIndex].deleteQueue + : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue; + (*dq) << e; +} + +void QSGD3D12EnginePrivate::deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h) +{ + PersistentFrameData::DeleteQueueEntry e; + e.cpuDescriptorPtr = h.ptr; + QVector<PersistentFrameData::DeleteQueueEntry> *dq = inFrame + ? &pframeData[currentPFrameIndex].deleteQueue + : &pframeData[(currentPFrameIndex + 1) % frameInFlightCount].outOfFrameDeleteQueue; + (*dq) << e; +} + +uint QSGD3D12EnginePrivate::genRenderTarget() +{ + return newId(&renderTargets); +} + +void QSGD3D12EnginePrivate::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples) +{ + Q_ASSERT(id); + const int idx = id - 1; + Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse()); + RenderTarget &rt(renderTargets[idx]); + + rt.rtv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + rt.dsv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + rt.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + samples = qMax(1, samples); + ID3D12Resource *res = createColorBuffer(rt.rtv, size, clearColor, samples); + if (res) + rt.color.Attach(res); + + ID3D12Resource *dsres = createDepthStencil(rt.dsv, size, samples); + if (dsres) + rt.ds.Attach(dsres); + + const bool multisample = rt.color->GetDesc().SampleDesc.Count > 1; + syncEntryFlags(&rt, RenderTarget::Multisample, multisample); + + if (!multisample) { + device->CreateShaderResourceView(rt.color.Get(), nullptr, rt.srv); + } else { + D3D12_HEAP_PROPERTIES defaultHeapProp = {}; + defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT; + + D3D12_RESOURCE_DESC textureDesc = {}; + textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + textureDesc.Width = size.width(); + textureDesc.Height = size.height(); + textureDesc.DepthOrArraySize = 1; + textureDesc.MipLevels = 1; + textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + textureDesc.SampleDesc.Count = 1; + textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + + HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc, + D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&rt.colorResolve)); + if (FAILED(hr)) { + qWarning("Failed to create resolve buffer: 0x%x", hr); + return; + } + + device->CreateShaderResourceView(rt.colorResolve.Get(), nullptr, rt.srv); + } + + if (Q_UNLIKELY(debug_render())) + qDebug("created new render target %u, size %dx%d, samples %d", id, size.width(), size.height(), samples); +} + +void QSGD3D12EnginePrivate::releaseRenderTarget(uint id) +{ + if (!id) + return; + + const int idx = id - 1; + Q_ASSERT(idx < renderTargets.count()); + RenderTarget &rt(renderTargets[idx]); + if (!rt.entryInUse()) + return; + + if (Q_UNLIKELY(debug_render())) + qDebug("releasing render target %u", id); + + if (rt.colorResolve) { + deferredDelete(rt.colorResolve); + rt.colorResolve = nullptr; + } + if (rt.color) { + deferredDelete(rt.color); + rt.color = nullptr; + deferredDelete(rt.rtv); + deferredDelete(rt.srv); + } + if (rt.ds) { + deferredDelete(rt.ds); + rt.ds = nullptr; + deferredDelete(rt.dsv); + } + + rt.flags &= ~RenderTarget::EntryInUse; +} + +void QSGD3D12EnginePrivate::activateRenderTargetAsTexture(uint id) +{ + if (!inFrame) { + qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__); + return; + } + + Q_ASSERT(id); + const int idx = id - 1; + Q_ASSERT(idx < renderTargets.count()); + RenderTarget &rt(renderTargets[idx]); + Q_ASSERT(rt.entryInUse() && rt.color); + + if (rt.flags & RenderTarget::NeedsReadBarrier) { + rt.flags &= ~RenderTarget::NeedsReadBarrier; + if (rt.flags & RenderTarget::Multisample) + resolveMultisampledTarget(rt.color.Get(), rt.colorResolve.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, commandList); + else + transitionResource(rt.color.Get(), commandList, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + + tframeData.activeTextures.append(TransientFrameData::ActiveTexture::ActiveTexture(TransientFrameData::ActiveTexture::TypeRenderTarget, id)); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h new file mode 100644 index 0000000000..84bb5a554e --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h @@ -0,0 +1,357 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12ENGINE_P_H +#define QSGD3D12ENGINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QWindow> +#include <QImage> +#include <QVector4D> +#include <qsggeometry.h> +#include <qt_windows.h> + +QT_BEGIN_NAMESPACE + +// No D3D or COM headers must be pulled in here. All that has to be isolated +// to engine_p_p.h and engine.cpp. + +class QSGD3D12EnginePrivate; + +// Shader bytecode and other strings are expected to be static so that a +// different pointer means a different shader. + +enum QSGD3D12Format { + FmtUnknown = 0, + + FmtFloat4 = 2, // DXGI_FORMAT_R32G32B32A32_FLOAT + FmtFloat3 = 6, // DXGI_FORMAT_R32G32B32_FLOAT + FmtFloat2 = 16, // DXGI_FORMAT_R32G32_FLOAT + FmtFloat = 41, // DXGI_FORMAT_R32_FLOAT + + // glVertexAttribPointer with GL_UNSIGNED_BYTE and normalized == true maps to the UNORM formats below + FmtUNormByte4 = 28, // DXGI_FORMAT_R8G8B8A8_UNORM + FmtUNormByte2 = 49, // DXGI_FORMAT_R8G8_UNORM + FmtUNormByte = 61, // DXGI_FORMAT_R8_UNORM + + // Index data types + FmtUnsignedShort = 57, // DXGI_FORMAT_R16_UINT + FmtUnsignedInt = 42 // DXGI_FORMAT_R32_UINT +}; + +struct QSGD3D12InputElement +{ + const char *semanticName = nullptr; + int semanticIndex = 0; + QSGD3D12Format format = FmtFloat4; + quint32 slot = 0; + quint32 offset = 0; + + bool operator==(const QSGD3D12InputElement &other) const { + return semanticName == other.semanticName && semanticIndex == other.semanticIndex + && format == other.format && slot == other.slot && offset == other.offset; + } +}; + +inline uint qHash(const QSGD3D12InputElement &key, uint seed = 0) +{ + return qHash(key.semanticName, seed) + key.semanticIndex + key.format + key.offset; +} + +struct QSGD3D12TextureView +{ + enum Filter { + FilterNearest = 0, + FilterLinear = 0x15, + FilterMinMagNearestMipLinear = 0x1, + FilterMinMagLinearMipNearest = 0x14 + }; + + enum AddressMode { + AddressWrap = 1, + AddressClamp = 3 + }; + + Filter filter = FilterLinear; + AddressMode addressModeHoriz = AddressClamp; + AddressMode addressModeVert = AddressClamp; + + bool operator==(const QSGD3D12TextureView &other) const { + return filter == other.filter + && addressModeHoriz == other.addressModeHoriz + && addressModeVert == other.addressModeVert; + } +}; + +inline uint qHash(const QSGD3D12TextureView &key, uint seed = 0) +{ + Q_UNUSED(seed); + return key.filter + key.addressModeHoriz + key.addressModeVert; +} + +struct QSGD3D12RootSignature +{ + QVector<QSGD3D12TextureView> textureViews; + + bool operator==(const QSGD3D12RootSignature &other) const { + return textureViews == other.textureViews; + } +}; + +inline uint qHash(const QSGD3D12RootSignature &key, uint seed = 0) +{ + return qHash(key.textureViews, seed); +} + +// Shader bytecode blobs and root signature-related data. +struct QSGD3D12ShaderState +{ + const quint8 *vs = nullptr; + quint32 vsSize = 0; + const quint8 *ps = nullptr; + quint32 psSize = 0; + + QSGD3D12RootSignature rootSig; + + bool operator==(const QSGD3D12ShaderState &other) const { + return vs == other.vs && vsSize == other.vsSize + && ps == other.ps && psSize == other.psSize + && rootSig == other.rootSig; + } +}; + +inline uint qHash(const QSGD3D12ShaderState &key, uint seed = 0) +{ + return qHash(key.vs, seed) + key.vsSize + qHash(key.ps, seed) + key.psSize + qHash(key.rootSig, seed); +} + +struct QSGD3D12PipelineState +{ + enum CullMode { + CullNone = 1, + CullFront, + CullBack + }; + + enum CompareFunc { + CompareNever = 1, + CompareLess, + CompareEqual, + CompareLessEqual, + CompareGreater, + CompareNotEqual, + CompareGreaterEqual, + CompareAlways + }; + + enum StencilOp { + StencilKeep = 1, + StencilZero, + StencilReplace, + StencilIncrSat, + StencilDecrSat, + StencilInvert, + StencilIncr, + StencilDescr + }; + + enum TopologyType { + TopologyTypePoint = 1, + TopologyTypeLine, + TopologyTypeTriangle + }; + + enum BlendType { + BlendNone, + BlendPremul, // == GL_ONE, GL_ONE_MINUS_SRC_ALPHA + BlendColor // == GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR + }; + + QSGD3D12ShaderState shaders; + + QVector<QSGD3D12InputElement> inputElements; + + CullMode cullMode = CullNone; + bool frontCCW = true; + bool colorWrite = true; + BlendType blend = BlendNone; + bool depthEnable = true; + CompareFunc depthFunc = CompareLess; + bool depthWrite = true; + bool stencilEnable = false; + CompareFunc stencilFunc = CompareEqual; + StencilOp stencilFailOp = StencilKeep; + StencilOp stencilDepthFailOp = StencilKeep; + StencilOp stencilPassOp = StencilKeep; + TopologyType topologyType = TopologyTypeTriangle; + + bool operator==(const QSGD3D12PipelineState &other) const { + return shaders == other.shaders + && inputElements == other.inputElements + && cullMode == other.cullMode + && frontCCW == other.frontCCW + && colorWrite == other.colorWrite + && blend == other.blend + && depthEnable == other.depthEnable + && (!depthEnable || depthFunc == other.depthFunc) + && depthWrite == other.depthWrite + && stencilEnable == other.stencilEnable + && (!stencilEnable || stencilFunc == other.stencilFunc) + && (!stencilEnable || stencilFailOp == other.stencilFailOp) + && (!stencilEnable || stencilDepthFailOp == other.stencilDepthFailOp) + && (!stencilEnable || stencilPassOp == other.stencilPassOp) + && topologyType == other.topologyType; + } +}; + +inline uint qHash(const QSGD3D12PipelineState &key, uint seed = 0) +{ + return qHash(key.shaders, seed) + qHash(key.inputElements, seed) + + key.cullMode + key.frontCCW + + key.colorWrite + key.blend + + key.depthEnable + key.depthWrite + + key.stencilEnable + + key.topologyType; +} + +class QSGD3D12Engine +{ +public: + QSGD3D12Engine(); + ~QSGD3D12Engine(); + + bool attachToWindow(WId window, const QSize &size, float dpr, int samples); + void releaseResources(); + bool hasResources() const; + void setWindowSize(const QSize &size, float dpr); + WId window() const; + QSize windowSize() const; + float windowDevicePixelRatio() const; + + void beginFrame(); + void endFrame(); + void beginLayer(); + void endLayer(); + + uint genBuffer(); + void releaseBuffer(uint id); + void resetBuffer(uint id, const quint8 *data, int size); + void markBufferDirty(uint id, int offset, int size); + + enum ClearFlag { + ClearDepth = 0x1, + ClearStencil = 0x2 + }; + Q_DECLARE_FLAGS(ClearFlags, ClearFlag) + + void queueViewport(const QRect &rect); + void queueScissor(const QRect &rect); + void queueSetRenderTarget(uint id = 0); + void queueClearRenderTarget(const QColor &color); + void queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which); + void queueSetBlendFactor(const QVector4D &factor); + void queueSetStencilRef(quint32 ref); + + void finalizePipeline(const QSGD3D12PipelineState &pipelineState); + + struct DrawParams { + QSGGeometry::DrawingMode mode = QSGGeometry::DrawTriangles; + int count = 0; + uint vertexBuf = 0; + uint indexBuf = 0; + uint constantBuf = 0; + int vboOffset = 0; + int vboSize = 0; + int vboStride = 0; + int cboOffset = 0; + int startIndexIndex = -1; + QSGD3D12Format indexFormat = FmtUnsignedShort; + }; + + void queueDraw(const DrawParams ¶ms); + + void present(); + void waitGPU(); + + static quint32 alignedConstantBufferSize(quint32 size); + static QSGD3D12Format toDXGIFormat(QSGGeometry::Type sgtype, int tupleSize = 1, int *size = nullptr); + static int mipMapLevels(const QSize &size); + static QSize mipMapAdjustedSourceSize(const QSize &size); + + enum TextureCreateFlag { + CreateWithAlpha = 0x1, + CreateWithMipMaps = 0x2 + }; + Q_DECLARE_FLAGS(TextureCreateFlags, TextureCreateFlag) + + uint genTexture(); + void createTexture(uint id, const QSize &size, QImage::Format format, TextureCreateFlags flags); + void queueTextureResize(uint id, const QSize &size); + void queueTextureUpload(uint id, const QImage &image, const QPoint &dstPos = QPoint()); + void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos); + void releaseTexture(uint id); + SIZE_T textureSRV(uint id) const; + void activateTexture(uint id); + + uint genRenderTarget(); + void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples); + void releaseRenderTarget(uint id); + void activateRenderTargetAsTexture(uint id); + +private: + QSGD3D12EnginePrivate *d; + Q_DISABLE_COPY(QSGD3D12Engine) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::ClearFlags) +Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Engine::TextureCreateFlags) + +QT_END_NAMESPACE + +#endif // QSGD3D12ENGINE_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h new file mode 100644 index 0000000000..40d1fdb510 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h @@ -0,0 +1,421 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12ENGINE_P_P_H +#define QSGD3D12ENGINE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qsgd3d12engine_p.h" +#include <QCache> + +#include <d3d12.h> +#include <dxgi1_4.h> +#include <wrl/client.h> + +using namespace Microsoft::WRL; + +// No moc-related features (Q_OBJECT, signals, etc.) can be used here to due +// moc-generated code failing to compile when combined with COM stuff. + +// Recommended reading before moving further: https://github.com/Microsoft/DirectXTK/wiki/ComPtr +// Note esp. operator= vs. Attach and operator& vs. GetAddressOf + +// ID3D12* is never passed to Qt containers directly. Always use ComPtr and put it into a struct. + +QT_BEGIN_NAMESPACE + +class QSGD3D12CPUDescriptorHeapManager +{ +public: + void initialize(ID3D12Device *device); + + void releaseResources(); + + D3D12_CPU_DESCRIPTOR_HANDLE allocate(D3D12_DESCRIPTOR_HEAP_TYPE type); + void release(D3D12_CPU_DESCRIPTOR_HANDLE handle, D3D12_DESCRIPTOR_HEAP_TYPE type); + quint32 handleSize(D3D12_DESCRIPTOR_HEAP_TYPE type) const { return m_handleSizes[type]; } + +private: + ID3D12Device *m_device = nullptr; + struct Heap { + D3D12_DESCRIPTOR_HEAP_TYPE type; + ComPtr<ID3D12DescriptorHeap> heap; + D3D12_CPU_DESCRIPTOR_HANDLE start; + quint32 handleSize; + quint32 freeMap[8]; + }; + QVector<Heap> m_heaps; + quint32 m_handleSizes[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; +}; + +class QSGD3D12DeviceManager +{ +public: + ID3D12Device *ref(); + void unref(); + void deviceLossDetected(); + IDXGIFactory4 *dxgi(); + + struct DeviceLossObserver { + virtual void deviceLost() = 0; + }; + void registerDeviceLossObserver(DeviceLossObserver *observer); + +private: + void ensureCreated(); + + ComPtr<ID3D12Device> m_device; + ComPtr<IDXGIFactory4> m_factory; + QAtomicInt m_ref; + QVector<DeviceLossObserver *> m_observers; +}; + +struct QSGD3D12CPUWaitableFence +{ + ~QSGD3D12CPUWaitableFence() { + if (event) + CloseHandle(event); + } + ComPtr<ID3D12Fence> fence; + HANDLE event = nullptr; + QAtomicInt value; +}; + +class QSGD3D12EnginePrivate : public QSGD3D12DeviceManager::DeviceLossObserver +{ +public: + void initialize(WId w, const QSize &size, float dpr, int samples); + bool isInitialized() const { return initialized; } + void releaseResources(); + void setWindowSize(const QSize &size, float dpr); + WId currentWindow() const { return window; } + QSize currentWindowSize() const { return windowSize; } + float currentWindowDpr() const { return windowDpr; } + + void beginFrame(); + void endFrame(); + void beginLayer(); + void endLayer(); + + uint genBuffer(); + void releaseBuffer(uint id); + void resetBuffer(uint id, const quint8 *data, int size); + void markBufferDirty(uint id, int offset, int size); + + void queueViewport(const QRect &rect); + void queueScissor(const QRect &rect); + void queueSetRenderTarget(uint id); + void queueClearRenderTarget(const QColor &color); + void queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which); + void queueSetBlendFactor(const QVector4D &factor); + void queueSetStencilRef(quint32 ref); + + void finalizePipeline(const QSGD3D12PipelineState &pipelineState); + + void queueDraw(const QSGD3D12Engine::DrawParams ¶ms); + + void present(); + void waitGPU(); + + uint genTexture(); + void createTexture(uint id, const QSize &size, QImage::Format format, QSGD3D12Engine::TextureCreateFlags flags); + void queueTextureResize(uint id, const QSize &size); + void queueTextureUpload(uint id, const QVector<QImage> &images, const QVector<QPoint> &dstPos); + void releaseTexture(uint id); + SIZE_T textureSRV(uint id) const; + void activateTexture(uint id); + + uint genRenderTarget(); + void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples); + void releaseRenderTarget(uint id); + void activateRenderTargetAsTexture(uint id); + + // the device is intentionally hidden here. all resources have to go + // through the engine and, unlike with GL, cannot just be created in random + // places due to the need for proper tracking, managing and releasing. +private: + void setupDefaultRenderTargets(); + void deviceLost() override; + + bool createCbvSrvUavHeap(int pframeIndex, int descriptorCount); + void setDescriptorHeaps(bool force = false); + void ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount); + + DXGI_SAMPLE_DESC makeSampleDesc(DXGI_FORMAT format, int samples); + ID3D12Resource *createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, + const QVector4D &clearColor, int samples); + ID3D12Resource *createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, int samples); + + QSGD3D12CPUWaitableFence *createCPUWaitableFence() const; + void waitForGPU(QSGD3D12CPUWaitableFence *f) const; + + void transitionResource(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList, + D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const; + void resolveMultisampledTarget(ID3D12Resource *msaa, ID3D12Resource *resolve, D3D12_RESOURCE_STATES resolveUsage, + ID3D12GraphicsCommandList *commandList) const; + void uavBarrier(ID3D12Resource *resource, ID3D12GraphicsCommandList *commandList) const; + + ID3D12Resource *createBuffer(int size); + + typedef QVector<QPair<int, int> > DirtyList; + void addDirtyRange(DirtyList *dirty, int offset, int size, int bufferSize); + + struct PersistentFrameData { + ComPtr<ID3D12DescriptorHeap> gpuCbvSrvUavHeap; + int gpuCbvSrvUavHeapSize; + int cbvSrvUavNextFreeDescriptorIndex; + QSet<uint> pendingTextureUploads; + QSet<uint> pendingTextureMipMap; + struct DeleteQueueEntry { + ComPtr<ID3D12Resource> res; + ComPtr<ID3D12DescriptorHeap> descHeap; + SIZE_T cpuDescriptorPtr = 0; + }; + QVector<DeleteQueueEntry> deleteQueue; + QVector<DeleteQueueEntry> outOfFrameDeleteQueue; + QSet<uint> buffersUsedInDrawCallSet; + QSet<uint> buffersUsedInFrame; + struct PendingRelease { + enum Type { + TypeTexture, + TypeBuffer + }; + Type type = TypeTexture; + uint id = 0; + PendingRelease(Type type, uint id) : type(type), id(id) { } + PendingRelease() { } + bool operator==(const PendingRelease &other) const { return type == other.type && id == other.id; } + }; + QSet<PendingRelease> pendingReleases; + QSet<PendingRelease> outOfFramePendingReleases; + }; + friend uint qHash(const PersistentFrameData::PendingRelease &pr, uint seed); + + void deferredDelete(ComPtr<ID3D12Resource> res); + void deferredDelete(ComPtr<ID3D12DescriptorHeap> dh); + void deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h); + + struct Buffer; + void ensureBuffer(Buffer *buf); + void updateBuffer(Buffer *buf); + + void beginDrawCalls(); + void beginFrameDraw(); + void endDrawCalls(bool lastInFrame = false); + + static const int MAX_SWAP_CHAIN_BUFFER_COUNT = 4; + static const int MAX_FRAME_IN_FLIGHT_COUNT = 4; + + bool initialized = false; + bool inFrame = false; + WId window = 0; + QSize windowSize; + float windowDpr; + int windowSamples; + int swapChainBufferCount; + int frameInFlightCount; + int waitableSwapChainMaxLatency; + ID3D12Device *device; + ComPtr<ID3D12CommandQueue> commandQueue; + ComPtr<ID3D12CommandQueue> copyCommandQueue; + ComPtr<IDXGISwapChain3> swapChain; + HANDLE swapEvent; + ComPtr<ID3D12Resource> backBufferRT[MAX_SWAP_CHAIN_BUFFER_COUNT]; + ComPtr<ID3D12Resource> defaultRT[MAX_SWAP_CHAIN_BUFFER_COUNT]; + D3D12_CPU_DESCRIPTOR_HANDLE defaultRTV[MAX_SWAP_CHAIN_BUFFER_COUNT]; + ComPtr<ID3D12Resource> defaultDS; + D3D12_CPU_DESCRIPTOR_HANDLE defaultDSV; + ComPtr<ID3D12CommandAllocator> frameCommandAllocator[MAX_FRAME_IN_FLIGHT_COUNT]; + ComPtr<ID3D12CommandAllocator> copyCommandAllocator; + ComPtr<ID3D12GraphicsCommandList> frameCommandList; + ComPtr<ID3D12GraphicsCommandList> copyCommandList; + QSGD3D12CPUDescriptorHeapManager cpuDescHeapManager; + quint64 presentFrameIndex; + quint64 frameIndex; + QSGD3D12CPUWaitableFence *presentFence = nullptr; + QSGD3D12CPUWaitableFence *frameFence[MAX_FRAME_IN_FLIGHT_COUNT]; + + PersistentFrameData pframeData[MAX_FRAME_IN_FLIGHT_COUNT]; + int currentPFrameIndex; + ID3D12GraphicsCommandList *commandList = nullptr; + int activeLayers = 0; + int currentLayerDepth = 0; + + struct PSOCacheEntry { + ComPtr<ID3D12PipelineState> pso; + }; + QCache<QSGD3D12PipelineState, PSOCacheEntry> psoCache; + struct RootSigCacheEntry { + ComPtr<ID3D12RootSignature> rootSig; + }; + QCache<QSGD3D12RootSignature, RootSigCacheEntry> rootSigCache; + + struct Texture { + enum Flag { + EntryInUse = 0x01, + Alpha = 0x02, + MipMap = 0x04 + }; + int flags = 0; + bool entryInUse() const { return flags & EntryInUse; } + bool alpha() const { return flags & Alpha; } + bool mipmap() const { return flags & MipMap; } + ComPtr<ID3D12Resource> texture; + D3D12_CPU_DESCRIPTOR_HANDLE srv; + quint64 fenceValue = 0; + quint64 lastWaitFenceValue = 0; + struct StagingHeap { + ComPtr<ID3D12Heap> heap; + }; + QVector<StagingHeap> stagingHeaps; + struct StagingBuffer { + ComPtr<ID3D12Resource> buffer; + }; + QVector<StagingBuffer> stagingBuffers; + QVector<D3D12_CPU_DESCRIPTOR_HANDLE> mipUAVs; + }; + + QVector<Texture> textures; + ComPtr<ID3D12Fence> textureUploadFence; + QAtomicInt nextTextureUploadFenceValue; + + struct TransientFrameData { + QSGGeometry::DrawingMode drawingMode; + uint currentIndexBuffer; + struct ActiveTexture { + enum Type { + TypeTexture, + TypeRenderTarget + }; + Type type = TypeTexture; + uint id = 0; + ActiveTexture(Type type, uint id) : type(type), id(id) { } + ActiveTexture() { } + }; + QVector<ActiveTexture> activeTextures; + int drawCount; + ID3D12PipelineState *lastPso; + ID3D12RootSignature *lastRootSig; + bool descHeapSet; + + QRect viewport; + QRect scissor; + QVector4D blendFactor = QVector4D(1, 1, 1, 1); + quint32 stencilRef = 1; + QSGD3D12PipelineState pipelineState; + }; + TransientFrameData tframeData; + + struct MipMapGen { + bool initialize(QSGD3D12EnginePrivate *enginePriv); + void releaseResources(); + void queueGenerate(const Texture &t); + + QSGD3D12EnginePrivate *engine; + ComPtr<ID3D12RootSignature> rootSig; + ComPtr<ID3D12PipelineState> pipelineState; + }; + + MipMapGen mipmapper; + + struct RenderTarget { + enum Flag { + EntryInUse = 0x01, + NeedsReadBarrier = 0x02, + Multisample = 0x04 + }; + int flags = 0; + bool entryInUse() const { return flags & EntryInUse; } + ComPtr<ID3D12Resource> color; + ComPtr<ID3D12Resource> colorResolve; + D3D12_CPU_DESCRIPTOR_HANDLE rtv; + ComPtr<ID3D12Resource> ds; + D3D12_CPU_DESCRIPTOR_HANDLE dsv; + D3D12_CPU_DESCRIPTOR_HANDLE srv; + }; + + QVector<RenderTarget> renderTargets; + uint currentRenderTarget; + + struct CPUBufferRef { + const quint8 *p = nullptr; + quint32 size = 0; + DirtyList dirty; + CPUBufferRef() { dirty.reserve(16); } + }; + + struct Buffer { + enum Flag { + EntryInUse = 0x01 + }; + int flags = 0; + bool entryInUse() const { return flags & EntryInUse; } + struct InFlightData { + ComPtr<ID3D12Resource> buffer; + DirtyList dirty; + quint32 dataSize = 0; + quint32 resourceSize = 0; + InFlightData() { dirty.reserve(16); } + }; + InFlightData d[MAX_FRAME_IN_FLIGHT_COUNT]; + CPUBufferRef cpuDataRef; + }; + + QVector<Buffer> buffers; +}; + +inline uint qHash(const QSGD3D12EnginePrivate::PersistentFrameData::PendingRelease &pr, uint seed = 0) +{ + Q_UNUSED(seed); + return pr.id + pr.type; +} + +QT_END_NAMESPACE + +#endif diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache.cpp new file mode 100644 index 0000000000..373e16d7c4 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12glyphcache_p.h" +#include "qsgd3d12engine_p.h" + +QT_BEGIN_NAMESPACE + +// NOTE: Avoid categorized logging. It is slow. + +#define DECLARE_DEBUG_VAR(variable) \ + static bool debug_ ## variable() \ + { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } + +DECLARE_DEBUG_VAR(render) + +QSGD3D12GlyphCache::QSGD3D12GlyphCache(QSGD3D12Engine *engine, QFontEngine::GlyphFormat format, const QTransform &matrix) + : QTextureGlyphCache(format, matrix), + m_engine(engine) +{ +} + +QSGD3D12GlyphCache::~QSGD3D12GlyphCache() +{ + if (m_id) + m_engine->releaseTexture(m_id); +} + +void QSGD3D12GlyphCache::createTextureData(int width, int height) +{ + width = qMax(128, width); + height = qMax(32, height); + + m_id = m_engine->genTexture(); + Q_ASSERT(m_id); + + if (Q_UNLIKELY(debug_render())) + qDebug("new glyph cache texture %u of size %dx%d, fontengine format %d", m_id, width, height, m_format); + + m_size = QSize(width, height); + + const QImage::Format imageFormat = + m_format == QFontEngine::Format_A8 ? QImage::Format_Alpha8 : QImage::Format_ARGB32_Premultiplied; + m_engine->createTexture(m_id, m_size, imageFormat, QSGD3D12Engine::CreateWithAlpha); +} + +void QSGD3D12GlyphCache::resizeTextureData(int width, int height) +{ + width = qMax(128, width); + height = qMax(32, height); + + if (m_size.width() >= width && m_size.height() >= height) + return; + + if (Q_UNLIKELY(debug_render())) + qDebug("glyph cache texture %u resize to %dx%d", m_id, width, height); + + m_size = QSize(width, height); + + m_engine->queueTextureResize(m_id, m_size); +} + +void QSGD3D12GlyphCache::beginFillTexture() +{ + Q_ASSERT(m_glyphImages.isEmpty() && m_glyphPos.isEmpty()); +} + +void QSGD3D12GlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) +{ + QImage mask = textureMapForGlyph(glyph, subPixelPosition); + const int maskWidth = mask.width(); + const int maskHeight = mask.height(); + + if (mask.format() == QImage::Format_Mono) { + mask = mask.convertToFormat(QImage::Format_Indexed8); + for (int y = 0; y < maskHeight; ++y) { + uchar *src = mask.scanLine(y); + for (int x = 0; x < maskWidth; ++x) + src[x] = -src[x]; // convert 0 and 1 into 0 and 255 + } + } else if (mask.depth() == 32) { + if (mask.format() == QImage::Format_RGB32) { + // We need to make the alpha component equal to the average of the RGB values. + // This is needed when drawing sub-pixel antialiased text on translucent targets. + for (int y = 0; y < maskHeight; ++y) { + QRgb *src = reinterpret_cast<QRgb *>(mask.scanLine(y)); + for (int x = 0; x < maskWidth; ++x) { + const int r = qRed(src[x]); + const int g = qGreen(src[x]); + const int b = qBlue(src[x]); + int avg; + if (mask.format() == QImage::Format_RGB32) + avg = (r + g + b + 1) / 3; // "+1" for rounding. + else // Format_ARGB32_Premultiplied + avg = qAlpha(src[x]); + src[x] = qRgba(r, g, b, avg); + } + } + } + } + + m_glyphImages.append(mask); + m_glyphPos.append(QPoint(c.x, c.y)); +} + +void QSGD3D12GlyphCache::endFillTexture() +{ + if (m_glyphImages.isEmpty()) + return; + + Q_ASSERT(m_id); + + m_engine->queueTextureUpload(m_id, m_glyphImages, m_glyphPos); + + // Nothing else left to do, it is up to the text material to call + // activateTexture() which will then add the texture dependency to the frame. + + m_glyphImages.clear(); + m_glyphPos.clear(); +} + +int QSGD3D12GlyphCache::glyphPadding() const +{ + return 1; +} + +int QSGD3D12GlyphCache::maxTextureWidth() const +{ + return 16384; +} + +int QSGD3D12GlyphCache::maxTextureHeight() const +{ + return 16384; +} + +void QSGD3D12GlyphCache::activateTexture() +{ + if (m_id) + m_engine->activateTexture(m_id); +} + +QSize QSGD3D12GlyphCache::currentSize() const +{ + return m_size; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache_p.h new file mode 100644 index 0000000000..a7430580a8 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphcache_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12GLYPHCACHE_P_H +#define QSGD3D12GLYPHCACHE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qtextureglyphcache_p.h> + +QT_BEGIN_NAMESPACE + +class QSGD3D12Engine; + +class QSGD3D12GlyphCache : public QTextureGlyphCache +{ +public: + QSGD3D12GlyphCache(QSGD3D12Engine *engine, QFontEngine::GlyphFormat format, const QTransform &matrix); + ~QSGD3D12GlyphCache(); + + void createTextureData(int width, int height) override; + void resizeTextureData(int width, int height) override; + void beginFillTexture() override; + void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) override; + void endFillTexture() override; + int glyphPadding() const override; + int maxTextureWidth() const override; + int maxTextureHeight() const override; + + void activateTexture(); + QSize currentSize() const; + +private: + QSGD3D12Engine *m_engine; + uint m_id = 0; + QVector<QImage> m_glyphImages; + QVector<QPoint> m_glyphPos; + QSize m_size; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12GLYPHCACHE_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode.cpp new file mode 100644 index 0000000000..e559739018 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12glyphnode_p.h" +#include "qsgd3d12builtinmaterials_p.h" + +QT_BEGIN_NAMESPACE + +void QSGD3D12GlyphNode::setMaterialColor(const QColor &color) +{ + static_cast<QSGD3D12TextMaterial *>(m_material)->setColor(color); +} + +void QSGD3D12GlyphNode::update() +{ + QRawFont font = m_glyphs.rawFont(); + QMargins margins(0, 0, 0, 0); + + if (m_style == QQuickText::Normal) { + // QSGBasicGlyphNode dtor will delete + m_material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Normal, m_rc, font); + } else if (m_style == QQuickText::Outline) { + QSGD3D12TextMaterial *material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Outlined, + m_rc, font, QFontEngine::Format_A8); + material->setStyleColor(m_styleColor); + m_material = material; + margins = QMargins(1, 1, 1, 1); + } else { + QSGD3D12TextMaterial *material = new QSGD3D12TextMaterial(QSGD3D12TextMaterial::Styled, + m_rc, font, QFontEngine::Format_A8); + if (m_style == QQuickText::Sunken) { + material->setStyleShift(QVector2D(0, -1)); + margins.setTop(1); + } else if (m_style == QQuickText::Raised) { + material->setStyleShift(QVector2D(0, 1)); + margins.setBottom(1); + } + material->setStyleColor(m_styleColor); + m_material = material; + } + + QSGD3D12TextMaterial *textMaterial = static_cast<QSGD3D12TextMaterial *>(m_material); + textMaterial->setColor(m_color); + + QRectF boundingRect; + textMaterial->populate(m_position, m_glyphs.glyphIndexes(), m_glyphs.positions(), geometry(), + &boundingRect, &m_baseLine, margins); + setBoundingRect(boundingRect); + + setMaterial(m_material); + markDirty(DirtyGeometry); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode_p.h new file mode 100644 index 0000000000..d04a8e8777 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12glyphnode_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12GLYPHNODE_P_H +#define QSGD3D12GLYPHNODE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgbasicglyphnode_p.h> + +QT_BEGIN_NAMESPACE + +class QSGD3D12RenderContext; + +class QSGD3D12GlyphNode : public QSGBasicGlyphNode +{ +public: + QSGD3D12GlyphNode(QSGD3D12RenderContext *rc) : m_rc(rc) { } + + void setMaterialColor(const QColor &color) override; + void update() override; + +private: + QSGD3D12RenderContext *m_rc; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12GLYPHNODE_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode.cpp new file mode 100644 index 0000000000..9bb360bc5e --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12imagenode_p.h" + +QT_BEGIN_NAMESPACE + +QSGD3D12ImageNode::QSGD3D12ImageNode() +{ + setMaterial(&m_material); +} + +void QSGD3D12ImageNode::setFiltering(QSGTexture::Filtering filtering) +{ + if (m_material.filtering() == filtering) + return; + + m_material.setFiltering(filtering); + m_smoothMaterial.setFiltering(filtering); + markDirty(DirtyMaterial); +} + +void QSGD3D12ImageNode::setMipmapFiltering(QSGTexture::Filtering filtering) +{ + if (m_material.mipmapFiltering() == filtering) + return; + + m_material.setMipmapFiltering(filtering); + m_smoothMaterial.setMipmapFiltering(filtering); + markDirty(DirtyMaterial); +} + +void QSGD3D12ImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode) +{ + if (m_material.verticalWrapMode() == wrapMode) + return; + + m_material.setVerticalWrapMode(wrapMode); + m_smoothMaterial.setVerticalWrapMode(wrapMode); + markDirty(DirtyMaterial); +} + +void QSGD3D12ImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) +{ + if (m_material.horizontalWrapMode() == wrapMode) + return; + + m_material.setHorizontalWrapMode(wrapMode); + m_smoothMaterial.setHorizontalWrapMode(wrapMode); + markDirty(DirtyMaterial); +} + +void QSGD3D12ImageNode::updateMaterialAntialiasing() +{ + if (m_antialiasing) + setMaterial(&m_smoothMaterial); + else + setMaterial(&m_material); +} + +void QSGD3D12ImageNode::setMaterialTexture(QSGTexture *texture) +{ + m_material.setTexture(texture); + m_smoothMaterial.setTexture(texture); +} + +QSGTexture *QSGD3D12ImageNode::materialTexture() const +{ + return m_material.texture(); +} + +bool QSGD3D12ImageNode::updateMaterialBlending() +{ + const bool alpha = m_material.flags() & QSGMaterial::Blending; + if (materialTexture() && alpha != materialTexture()->hasAlphaChannel()) { + m_material.setFlag(QSGMaterial::Blending, !alpha); + return true; + } + return false; +} + +bool QSGD3D12ImageNode::supportsWrap(const QSize &) const +{ + return true; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode_p.h new file mode 100644 index 0000000000..ef4b38884a --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12imagenode_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12IMAGENODE_P_H +#define QSGD3D12IMAGENODE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgbasicimagenode_p.h> +#include "qsgd3d12builtinmaterials_p.h" + +QT_BEGIN_NAMESPACE + +class QSGD3D12ImageNode : public QSGBasicImageNode +{ +public: + QSGD3D12ImageNode(); + + void setMipmapFiltering(QSGTexture::Filtering filtering) override; + void setFiltering(QSGTexture::Filtering filtering) override; + void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) override; + void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) override; + + void updateMaterialAntialiasing() override; + void setMaterialTexture(QSGTexture *texture) override; + QSGTexture *materialTexture() const override; + bool updateMaterialBlending() override; + bool supportsWrap(const QSize &size) const override; + +private: + QSGD3D12TextureMaterial m_material; + QSGD3D12SmoothTextureMaterial m_smoothMaterial; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12IMAGENODE_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp new file mode 100644 index 0000000000..6623c51f5c --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp @@ -0,0 +1,329 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12layer_p.h" +#include "qsgd3d12rendercontext_p.h" +#include "qsgd3d12engine_p.h" +#include "qsgd3d12renderer_p.h" + +QT_BEGIN_NAMESPACE + +// NOTE: Avoid categorized logging. It is slow. + +#define DECLARE_DEBUG_VAR(variable) \ + static bool debug_ ## variable() \ + { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } + +DECLARE_DEBUG_VAR(render) + +QSGD3D12Layer::QSGD3D12Layer(QSGD3D12RenderContext *rc) + : m_rc(rc) +{ + if (Q_UNLIKELY(debug_render())) + qDebug("new layer %p", this); +} + +QSGD3D12Layer::~QSGD3D12Layer() +{ + if (Q_UNLIKELY(debug_render())) + qDebug("destroying layer %p", this); + + cleanup(); +} + +// QSGTexture + +int QSGD3D12Layer::textureId() const +{ + return m_rt; // not a texture id per se but will do +} + +QSize QSGD3D12Layer::textureSize() const +{ + return m_size; +} + +bool QSGD3D12Layer::hasAlphaChannel() const +{ + return true; +} + +bool QSGD3D12Layer::hasMipmaps() const +{ + // mipmapped layers are not supported for now + return false; +} + +QRectF QSGD3D12Layer::normalizedTextureSubRect() const +{ + // (0, 0) is the top-left corner, unlike OpenGL. Hence the inversion of + // m_mirrorVertical, as opposed to the GL version. + return QRectF(m_mirrorHorizontal ? 1 : 0, + m_mirrorVertical ? 1 : 0, + m_mirrorHorizontal ? -1 : 1, + m_mirrorVertical ? -1 : 1); +} + +void QSGD3D12Layer::bind() +{ + if (Q_UNLIKELY(debug_render())) + qDebug("layer %p bind rt=%u", this, m_rt); + + // ### + + m_rc->engine()->activateRenderTargetAsTexture(m_rt); +} + +// QSGDynamicTexture + +bool QSGD3D12Layer::updateTexture() +{ + if (Q_UNLIKELY(debug_render())) + qDebug("layer %p updateTexture", this); + + const bool doUpdate = (m_live || m_updateContentPending) && m_dirtyTexture; + + if (doUpdate) + updateContent(); + + if (m_updateContentPending) { + m_updateContentPending = false; + emit scheduledUpdateCompleted(); + } + + return doUpdate; +} + +// QSGLayer + +void QSGD3D12Layer::setItem(QSGNode *item) +{ + if (m_item == item) + return; + + if (m_live && !item) + resetRenderTarget(); + + m_item = item; + markDirtyTexture(); +} + +void QSGD3D12Layer::setRect(const QRectF &rect) +{ + if (m_rect == rect) + return; + + m_rect = rect; + markDirtyTexture(); +} + +void QSGD3D12Layer::setSize(const QSize &size) +{ + if (m_size == size) + return; + + if (m_live && size.isNull()) + resetRenderTarget(); + + m_size = size; + markDirtyTexture(); +} + +void QSGD3D12Layer::scheduleUpdate() +{ + if (m_updateContentPending) + return; + + if (Q_UNLIKELY(debug_render())) + qDebug("layer %p scheduleUpdate", this); + + m_updateContentPending = true; + + if (m_dirtyTexture) + emit updateRequested(); +} + +QImage QSGD3D12Layer::toImage() const +{ + // ### figure out something for item grab support + return QImage(); +} + +void QSGD3D12Layer::setLive(bool live) +{ + if (m_live == live) + return; + + if (live && (!m_item || m_size.isNull())) + resetRenderTarget(); + + m_live = live; + markDirtyTexture(); +} + +void QSGD3D12Layer::setRecursive(bool recursive) +{ + m_recursive = recursive; +} + +void QSGD3D12Layer::setFormat(uint format) +{ + Q_UNUSED(format); +} + +void QSGD3D12Layer::setHasMipmaps(bool mipmap) +{ + // mipmapped layers are not supported for now + Q_UNUSED(mipmap); +} + +void QSGD3D12Layer::setDevicePixelRatio(qreal ratio) +{ + m_dpr = ratio; +} + +void QSGD3D12Layer::setMirrorHorizontal(bool mirror) +{ + m_mirrorHorizontal = mirror; +} + +void QSGD3D12Layer::setMirrorVertical(bool mirror) +{ + m_mirrorVertical = mirror; +} + +void QSGD3D12Layer::markDirtyTexture() +{ + if (Q_UNLIKELY(debug_render())) + qDebug("layer %p markDirtyTexture", this); + + m_dirtyTexture = true; + + if (m_live || m_updateContentPending) + emit updateRequested(); +} + +void QSGD3D12Layer::invalidated() +{ + cleanup(); +} + +void QSGD3D12Layer::cleanup() +{ + if (!m_renderer && !m_rt) + return; + + if (Q_UNLIKELY(debug_render())) + qDebug("layer %p cleanup renderer=%p rt=%u", this, m_renderer, m_rt); + + delete m_renderer; + m_renderer = nullptr; + + resetRenderTarget(); +} + +void QSGD3D12Layer::resetRenderTarget() +{ + if (!m_rt) + return; + + if (Q_UNLIKELY(debug_render())) + qDebug("layer %p resetRenderTarget rt=%u", this, m_rt); + + m_rc->engine()->releaseRenderTarget(m_rt); + m_rt = 0; +} + +void QSGD3D12Layer::updateContent() +{ + if (Q_UNLIKELY(debug_render())) + qDebug("layer %p updateContent", this); + + if (!m_item || m_size.isNull()) { + resetRenderTarget(); + m_dirtyTexture = false; + return; + } + + QSGNode *root = m_item; + while (root->firstChild() && root->type() != QSGNode::RootNodeType) + root = root->firstChild(); + + if (root->type() != QSGNode::RootNodeType) + return; + + if (!m_renderer) { + m_renderer = m_rc->createRenderer(); + static_cast<QSGD3D12Renderer *>(m_renderer)->turnToLayerRenderer(); + connect(m_renderer, &QSGRenderer::sceneGraphChanged, this, &QSGD3D12Layer::markDirtyTexture); + } + + m_renderer->setDevicePixelRatio(m_dpr); + m_renderer->setRootNode(static_cast<QSGRootNode *>(root)); + + if (!m_rt || m_rtSize != m_size) { + // ### recursive, multisample + + if (m_rt) + resetRenderTarget(); + + m_rt = m_rc->engine()->genRenderTarget(); + m_rtSize = m_size; + m_rc->engine()->createRenderTarget(m_rt, m_rtSize, QVector4D(0, 0, 0, 0), 0); + } + + m_dirtyTexture = false; + + m_renderer->setDeviceRect(m_size); + m_renderer->setViewportRect(m_size); + QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(), + m_mirrorVertical ? m_rect.bottom() : m_rect.top(), + m_mirrorHorizontal ? -m_rect.width() : m_rect.width(), + m_mirrorVertical ? -m_rect.height() : m_rect.height()); + m_renderer->setProjectionMatrixToRect(mirrored); + m_renderer->setClearColor(Qt::transparent); + + // ### recursive, multisample + m_renderer->renderScene(m_rt); + + if (m_recursive) + markDirtyTexture(); // Continuously update if 'live' and 'recursive'. +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h new file mode 100644 index 0000000000..d167cf4f66 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12LAYER_P_H +#define QSGD3D12LAYER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +class QSGD3D12RenderContext; + +class QSGD3D12Layer : public QSGLayer +{ + Q_OBJECT + +public: + QSGD3D12Layer(QSGD3D12RenderContext *rc); + ~QSGD3D12Layer(); + + int textureId() const override; + QSize textureSize() const override; + bool hasAlphaChannel() const override; + bool hasMipmaps() const override; + QRectF normalizedTextureSubRect() const override; + void bind() override; + + bool updateTexture() override; + + void setItem(QSGNode *item) override; + void setRect(const QRectF &rect) override; + void setSize(const QSize &size) override; + void scheduleUpdate() override; + QImage toImage() const override; + void setLive(bool live) override; + void setRecursive(bool recursive) override; + void setFormat(uint format) override; + void setHasMipmaps(bool mipmap) override; + void setDevicePixelRatio(qreal ratio) override; + void setMirrorHorizontal(bool mirror) override; + void setMirrorVertical(bool mirror) override; + +public Q_SLOTS: + void markDirtyTexture() override; + void invalidated() override; + +private: + void cleanup(); + void resetRenderTarget(); + void updateContent(); + + QSGD3D12RenderContext *m_rc; + uint m_rt = 0; + QSize m_rtSize; + QSize m_size; + QRectF m_rect; + QSGNode *m_item = nullptr; + QSGRenderer *m_renderer = nullptr; + float m_dpr = 1; + bool m_mirrorHorizontal = false; + bool m_mirrorVertical = true; + bool m_live = true; + bool m_recursive = false; + bool m_dirtyTexture = true; + bool m_updateContentPending = false; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12LAYER_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp new file mode 100644 index 0000000000..3412a4b63b --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12material_p.h" +#include <private/qsgrenderer_p.h> + +QT_BEGIN_NAMESPACE + +QSGD3D12Material::RenderState QSGD3D12Material::makeRenderState(QSGRenderer *renderer, RenderState::DirtyStates dirty) +{ + RenderState rs; + rs.m_dirty = dirty; + rs.m_data = renderer; + return rs; +} + +float QSGD3D12Material::RenderState::opacity() const +{ + Q_ASSERT(m_data); + return static_cast<const QSGRenderer *>(m_data)->currentOpacity(); +} + +float QSGD3D12Material::RenderState::determinant() const +{ + Q_ASSERT(m_data); + return static_cast<const QSGRenderer *>(m_data)->determinant(); +} + +QMatrix4x4 QSGD3D12Material::RenderState::combinedMatrix() const +{ + Q_ASSERT(m_data); + return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix(); +} + +float QSGD3D12Material::RenderState::devicePixelRatio() const +{ + Q_ASSERT(m_data); + return static_cast<const QSGRenderer *>(m_data)->devicePixelRatio(); +} + +QMatrix4x4 QSGD3D12Material::RenderState::modelViewMatrix() const +{ + Q_ASSERT(m_data); + return static_cast<const QSGRenderer *>(m_data)->currentModelViewMatrix(); +} + +QMatrix4x4 QSGD3D12Material::RenderState::projectionMatrix() const +{ + Q_ASSERT(m_data); + return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix(); +} + +QRect QSGD3D12Material::RenderState::viewportRect() const +{ + Q_ASSERT(m_data); + return static_cast<const QSGRenderer *>(m_data)->viewportRect(); +} + +QRect QSGD3D12Material::RenderState::deviceRect() const +{ + Q_ASSERT(m_data); + return static_cast<const QSGRenderer *>(m_data)->deviceRect(); +} + +QSGMaterialShader *QSGD3D12Material::createShader() const +{ + return nullptr; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h new file mode 100644 index 0000000000..e9af8e68a0 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12material_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12MATERIAL_P_H +#define QSGD3D12MATERIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qsgmaterial.h> +#include "qsgd3d12engine_p.h" + +QT_BEGIN_NAMESPACE + +class QSGRenderer; + +// The D3D renderer works with QSGD3D12Material as the "base" class since +// QSGMaterial and its GL program related bits are not suitable. Also, there is +// no split like with QSGMaterialShader. + +class QSGD3D12Material : public QSGMaterial +{ +public: + struct RenderState { + enum DirtyState { + DirtyMatrix = 0x0001, + DirtyOpacity = 0x0002, + DirtyCachedMaterialData = 0x0004, + DirtyAll = 0xFFFF + }; + Q_DECLARE_FLAGS(DirtyStates, DirtyState) + + DirtyStates dirtyStates() const { return m_dirty; } + + bool isMatrixDirty() const { return m_dirty & DirtyMatrix; } + bool isOpacityDirty() const { return m_dirty & DirtyOpacity; } + bool isCachedMaterialDataDirty() const { return m_dirty & DirtyCachedMaterialData; } + + float opacity() const; + QMatrix4x4 combinedMatrix() const; + QMatrix4x4 modelViewMatrix() const; + QMatrix4x4 projectionMatrix() const; + QRect viewportRect() const; + QRect deviceRect() const; + float determinant() const; + float devicePixelRatio() const; + + DirtyStates m_dirty = 0; + void *m_data = nullptr; + }; + + struct ExtraState { + QVector4D blendFactor; + }; + + enum UpdateResult { + UpdatedShaders = 0x0001, + UpdatedConstantBuffer = 0x0002, + UpdatedBlendFactor = 0x0004 + }; + Q_DECLARE_FLAGS(UpdateResults, UpdateResult) + + static RenderState makeRenderState(QSGRenderer *renderer, RenderState::DirtyStates dirty); + + virtual int constantBufferSize() const = 0; + virtual void preparePipeline(QSGD3D12PipelineState *pipelineState) = 0; + virtual UpdateResults updatePipeline(const RenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *extraState, + quint8 *constantBuffer) = 0; + +private: + QSGMaterialShader *createShader() const override; // dummy, QSGMaterialShader is too GL dependent +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Material::RenderState::DirtyStates) +Q_DECLARE_OPERATORS_FOR_FLAGS(QSGD3D12Material::UpdateResults) + +QT_END_NAMESPACE + +#endif // QSGD3D12MATERIAL_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp new file mode 100644 index 0000000000..7548f5cbc0 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12rectanglenode_p.h" + +QT_BEGIN_NAMESPACE + +QSGD3D12RectangleNode::QSGD3D12RectangleNode() +{ + setMaterial(&m_material); +} + +void QSGD3D12RectangleNode::updateMaterialAntialiasing() +{ + if (m_antialiasing) + setMaterial(&m_smoothMaterial); + else + setMaterial(&m_material); +} + +void QSGD3D12RectangleNode::updateMaterialBlending(QSGNode::DirtyState *state) +{ + // smoothed material is always blended, so no change in material state + if (material() == &m_material) { + bool wasBlending = (m_material.flags() & QSGMaterial::Blending); + bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque) + || (m_color.alpha() < 255 && m_color.alpha() != 0) + || (m_pen_width > 0 && m_border_color.alpha() < 255); + if (wasBlending != isBlending) { + m_material.setFlag(QSGMaterial::Blending, isBlending); + *state |= QSGNode::DirtyMaterial; + } + } +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h new file mode 100644 index 0000000000..95f734bc4c --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rectanglenode_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12RECTANGLENODE_P_H +#define QSGD3D12RECTANGLENODE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgbasicrectanglenode_p.h> +#include "qsgd3d12builtinmaterials_p.h" + +QT_BEGIN_NAMESPACE + +class QSGD3D12RectangleNode : public QSGBasicRectangleNode +{ +public: + QSGD3D12RectangleNode(); + +private: + void updateMaterialAntialiasing() override; + void updateMaterialBlending(QSGNode::DirtyState *state) override; + + QSGD3D12VertexColorMaterial m_material; + QSGD3D12SmoothColorMaterial m_smoothMaterial; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12RECTANGLENODE_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp new file mode 100644 index 0000000000..af3e8e36ee --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12rendercontext_p.h" +#include "qsgd3d12renderer_p.h" +#include "qsgd3d12texture_p.h" + +QT_BEGIN_NAMESPACE + +// NOTE: Avoid categorized logging. It is slow. + +#define DECLARE_DEBUG_VAR(variable) \ + static bool debug_ ## variable() \ + { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } + +DECLARE_DEBUG_VAR(render) + +QSGD3D12RenderContext::QSGD3D12RenderContext(QSGContext *ctx) + : QSGRenderContext(ctx) +{ +} + +void QSGD3D12RenderContext::invalidate() +{ + if (Q_UNLIKELY(debug_render())) + qDebug("rendercontext invalidate engine %p, %d/%d/%d", m_engine, + m_texturesToDelete.count(), m_textures.count(), m_fontEnginesToClean.count()); + + qDeleteAll(m_texturesToDelete); + m_texturesToDelete.clear(); + + qDeleteAll(m_textures); + m_textures.clear(); + + for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(), + end = m_fontEnginesToClean.constEnd(); it != end; ++it) { + (*it)->clearGlyphCache(m_engine); + if (!(*it)->ref.deref()) + delete *it; + } + m_fontEnginesToClean.clear(); + + m_sg->renderContextInvalidated(this); + emit invalidated(); +} + +QSGTexture *QSGD3D12RenderContext::createTexture(const QImage &image, uint flags) const +{ + Q_ASSERT(m_engine); + QSGD3D12Texture *t = new QSGD3D12Texture(m_engine); + t->setImage(image, flags); + return t; +} + + QSGRenderer *QSGD3D12RenderContext::createRenderer() +{ + return new QSGD3D12Renderer(this); +} + +void QSGD3D12RenderContext::renderNextFrame(QSGRenderer *renderer, uint fbo) +{ + static_cast<QSGD3D12Renderer *>(renderer)->renderScene(fbo); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h new file mode 100644 index 0000000000..1acb7e4205 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12RENDERCONTEXT_P_H +#define QSGD3D12RENDERCONTEXT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgcontext_p.h> + +QT_BEGIN_NAMESPACE + +class QSGD3D12Engine; + +class QSGD3D12RenderContext : public QSGRenderContext +{ +public: + QSGD3D12RenderContext(QSGContext *ctx); + void invalidate() override; + void renderNextFrame(QSGRenderer *renderer, uint fbo) override; + QSGTexture *createTexture(const QImage &image, uint flags) const override; + QSGRenderer *createRenderer() override; + + void setEngine(QSGD3D12Engine *engine) { m_engine = engine; } + QSGD3D12Engine *engine() { return m_engine; } + +private: + QSGD3D12Engine *m_engine = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12RENDERCONTEXT_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp new file mode 100644 index 0000000000..7f8b10f003 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp @@ -0,0 +1,710 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12renderer_p.h" +#include "qsgd3d12rendercontext_p.h" +#include <private/qsgnodeupdater_p.h> + +#include "vs_stencilclip.hlslh" +#include "ps_stencilclip.hlslh" + +//#define I_LIKE_STENCIL + +QT_BEGIN_NAMESPACE + +#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling()) + +// NOTE: Avoid categorized logging. It is slow. + +#define DECLARE_DEBUG_VAR(variable) \ + static bool debug_ ## variable() \ + { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } + +DECLARE_DEBUG_VAR(build) +DECLARE_DEBUG_VAR(change) +DECLARE_DEBUG_VAR(render) + +class DummyUpdater : public QSGNodeUpdater +{ +public: + void updateState(QSGNode *) { }; +}; + +QSGD3D12Renderer::QSGD3D12Renderer(QSGRenderContext *context) + : QSGRenderer(context), + m_renderList(16), + m_vboData(1024), + m_iboData(256), + m_cboData(4096) +{ + setNodeUpdater(new DummyUpdater); + m_freshPipelineState.shaders.rootSig.textureViews.reserve(4); +} + +QSGD3D12Renderer::~QSGD3D12Renderer() +{ + if (m_engine) { + m_engine->releaseBuffer(m_vertexBuf); + m_engine->releaseBuffer(m_indexBuf); + m_engine->releaseBuffer(m_constantBuf); + } +} + +void QSGD3D12Renderer::renderScene(GLuint fboId) +{ + m_renderTarget = fboId; + + struct DummyBindable : public QSGBindable { + void bind() const { } + } bindable; + + QSGRenderer::renderScene(bindable); // calls back render() +} + +// Search through the node set and remove nodes that are descendants of other +// nodes in the same set. +static QSet<QSGNode *> qsg_removeDescendants(const QSet<QSGNode *> &nodes, QSGRootNode *root) +{ + QSet<QSGNode *> result = nodes; + for (QSGNode *node : nodes) { + QSGNode *n = node; + while (n != root) { + if (n != node && result.contains(n)) { + result.remove(node); + break; + } + n = n->parent(); + } + } + return result; +} + +void QSGD3D12Renderer::updateMatrices(QSGNode *node, QSGTransformNode *xform) +{ + if (node->isSubtreeBlocked()) + return; + + if (node->type() == QSGNode::TransformNodeType) { + QSGTransformNode *tn = static_cast<QSGTransformNode *>(node); + if (xform) + tn->setCombinedMatrix(xform->combinedMatrix() * tn->matrix()); + else + tn->setCombinedMatrix(tn->matrix()); + QSGNODE_TRAVERSE(node) + updateMatrices(child, tn); + } else { + if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) { + m_nodeDirtyMap[node] |= QSGD3D12Material::RenderState::DirtyMatrix; + QSGBasicGeometryNode *gnode = static_cast<QSGBasicGeometryNode *>(node); + const QMatrix4x4 *newMatrix = xform ? &xform->combinedMatrix() : nullptr; + // NB the newMatrix ptr is usually the same as before as it just + // references the transform node's own matrix. + gnode->setMatrix(newMatrix); + } + QSGNODE_TRAVERSE(node) + updateMatrices(child, xform); + } +} + +void QSGD3D12Renderer::updateOpacities(QSGNode *node, float inheritedOpacity) +{ + if (node->isSubtreeBlocked()) + return; + + if (node->type() == QSGNode::OpacityNodeType) { + QSGOpacityNode *on = static_cast<QSGOpacityNode *>(node); + float combined = inheritedOpacity * on->opacity(); + on->setCombinedOpacity(combined); + QSGNODE_TRAVERSE(node) + updateOpacities(child, combined); + } else { + if (node->type() == QSGNode::GeometryNodeType) { + m_nodeDirtyMap[node] |= QSGD3D12Material::RenderState::DirtyOpacity; + QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(node); + gn->setInheritedOpacity(inheritedOpacity); + } + QSGNODE_TRAVERSE(node) + updateOpacities(child, inheritedOpacity); + } +} + +void QSGD3D12Renderer::buildRenderList(QSGNode *node, QSGClipNode *clip) +{ + if (node->isSubtreeBlocked()) + return; + + if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) { + QSGBasicGeometryNode *gn = static_cast<QSGBasicGeometryNode *>(node); + QSGGeometry *g = gn->geometry(); + + Element e; + e.node = gn; + + if (g->vertexCount() > 0) { + e.vboOffset = m_vboData.size(); + const int vertexSize = g->sizeOfVertex() * g->vertexCount(); + m_vboData.resize(m_vboData.size() + vertexSize); + memcpy(m_vboData.data() + e.vboOffset, g->vertexData(), vertexSize); + } + + if (g->indexCount() > 0) { + e.iboOffset = m_iboData.size(); + e.iboStride = g->sizeOfIndex(); + const int indexSize = e.iboStride * g->indexCount(); + m_iboData.resize(m_iboData.size() + indexSize); + memcpy(m_iboData.data() + e.iboOffset, g->indexData(), indexSize); + } + + e.cboOffset = m_cboData.size(); + if (node->type() == QSGNode::GeometryNodeType) { + QSGD3D12Material *m = static_cast<QSGD3D12Material *>(static_cast<QSGGeometryNode *>(node)->activeMaterial()); + e.cboSize = m->constantBufferSize(); + } else { + // Stencil-based clipping needs a 4x4 matrix. + e.cboSize = QSGD3D12Engine::alignedConstantBufferSize(16 * sizeof(float)); + } + m_cboData.resize(m_cboData.size() + e.cboSize); + + m_renderList.add(e); + + gn->setClipList(clip); + if (node->type() == QSGNode::ClipNodeType) + clip = static_cast<QSGClipNode *>(node); + } + + QSGNODE_TRAVERSE(node) + buildRenderList(child, clip); +} + +void QSGD3D12Renderer::render() +{ + QSGD3D12RenderContext *rc = static_cast<QSGD3D12RenderContext *>(context()); + m_engine = rc->engine(); + if (!m_layerRenderer) + m_engine->beginFrame(); + else + m_engine->beginLayer(); + + m_activeScissorRect = QRect(); + + if (m_rebuild) { + m_rebuild = false; + + m_dirtyTransformNodes.clear(); + m_dirtyTransformNodes.insert(rootNode()); + m_dirtyOpacityNodes.clear(); + m_dirtyOpacityNodes.insert(rootNode()); + + m_renderList.reset(); + m_vboData.reset(); + m_iboData.reset(); + m_cboData.reset(); + + buildRenderList(rootNode(), nullptr); + + if (!m_vertexBuf) + m_vertexBuf = m_engine->genBuffer(); + m_engine->resetBuffer(m_vertexBuf, m_vboData.data(), m_vboData.size()); + + if (!m_constantBuf) + m_constantBuf = m_engine->genBuffer(); + m_engine->resetBuffer(m_constantBuf, m_cboData.data(), m_cboData.size()); + + if (m_iboData.size()) { + if (!m_indexBuf) + m_indexBuf = m_engine->genBuffer(); + m_engine->resetBuffer(m_indexBuf, m_iboData.data(), m_iboData.size()); + } else if (m_indexBuf) { + m_engine->releaseBuffer(m_indexBuf); + m_indexBuf = 0; + } + + if (Q_UNLIKELY(debug_build())) { + qDebug("renderList: %d elements in total", m_renderList.size()); + for (int i = 0; i < m_renderList.size(); ++i) { + const Element &e = m_renderList.at(i); + qDebug() << " - " << e.vboOffset << e.iboOffset << e.cboOffset << e.cboSize << e.node; + } + } + } + + const QRect devRect = deviceRect(); + m_projectionChangedDueToDeviceSize = devRect != m_lastDeviceRect; + if (m_projectionChangedDueToDeviceSize) + m_lastDeviceRect = devRect; + + if (m_dirtyTransformNodes.size()) { + const QSet<QSGNode *> subTreeRoots = qsg_removeDescendants(m_dirtyTransformNodes, rootNode()); + for (QSGNode *node : subTreeRoots) { + // First find the parent transform so we have the accumulated + // matrix up until this point. + QSGTransformNode *xform = 0; + QSGNode *n = node; + if (n->type() == QSGNode::TransformNodeType) + n = node->parent(); + while (n != rootNode() && n->type() != QSGNode::TransformNodeType) + n = n->parent(); + if (n != rootNode()) + xform = static_cast<QSGTransformNode *>(n); + + // Then update in the subtree + updateMatrices(node, xform); + } + } + + if (m_dirtyOpacityNodes.size()) { + const QSet<QSGNode *> subTreeRoots = qsg_removeDescendants(m_dirtyOpacityNodes, rootNode()); + for (QSGNode *node : subTreeRoots) { + float opacity = 1.0f; + QSGNode *n = node; + if (n->type() == QSGNode::OpacityNodeType) + n = node->parent(); + while (n != rootNode() && n->type() != QSGNode::OpacityNodeType) + n = n->parent(); + if (n != rootNode()) + opacity = static_cast<QSGOpacityNode *>(n)->combinedOpacity(); + + updateOpacities(node, opacity); + } + m_dirtyOpaqueElements = true; + } + + if (m_dirtyOpaqueElements) { + m_dirtyOpaqueElements = false; + m_opaqueElements.clear(); + m_opaqueElements.resize(m_renderList.size()); + for (int i = 0; i < m_renderList.size(); ++i) { + const Element &e = m_renderList.at(i); + if (e.node->type() == QSGNode::GeometryNodeType) { + const QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(e.node); + if (gn->inheritedOpacity() > 0.999f && ((gn->activeMaterial()->flags() & QSGMaterial::Blending) == 0)) + m_opaqueElements.setBit(i); + } + } + } + + // Build pipeline state and draw calls. + renderElements(); + + m_dirtyTransformNodes.clear(); + m_dirtyOpacityNodes.clear(); + m_dirtyOpaqueElements = false; + m_nodeDirtyMap.clear(); + + // Finalize buffers and execute commands. + if (!m_layerRenderer) + m_engine->endFrame(); + else + m_engine->endLayer(); +} + +void QSGD3D12Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) +{ + // note that with DirtyNodeRemoved the window and all the graphics engine may already be gone + + if (Q_UNLIKELY(debug_change())) { + QDebug debug = qDebug(); + debug << "dirty:"; + if (state & QSGNode::DirtyGeometry) + debug << "Geometry"; + if (state & QSGNode::DirtyMaterial) + debug << "Material"; + if (state & QSGNode::DirtyMatrix) + debug << "Matrix"; + if (state & QSGNode::DirtyNodeAdded) + debug << "Added"; + if (state & QSGNode::DirtyNodeRemoved) + debug << "Removed"; + if (state & QSGNode::DirtyOpacity) + debug << "Opacity"; + if (state & QSGNode::DirtySubtreeBlocked) + debug << "SubtreeBlocked"; + if (state & QSGNode::DirtyForceUpdate) + debug << "ForceUpdate"; + + // when removed, some parts of the node could already have been destroyed + // so don't debug it out. + if (state & QSGNode::DirtyNodeRemoved) + debug << (void *) node << node->type(); + else + debug << node; + } + + if (state & (QSGNode::DirtyNodeAdded + | QSGNode::DirtyNodeRemoved + | QSGNode::DirtySubtreeBlocked + | QSGNode::DirtyGeometry + | QSGNode::DirtyForceUpdate)) + m_rebuild = true; + + if (state & QSGNode::DirtyMatrix) + m_dirtyTransformNodes << node; + + if (state & QSGNode::DirtyOpacity) + m_dirtyOpacityNodes << node; + + if (state & QSGNode::DirtyMaterial) + m_dirtyOpaqueElements = true; + + QSGRenderer::nodeChanged(node, state); +} + +void QSGD3D12Renderer::renderElements() +{ + m_engine->queueSetRenderTarget(m_renderTarget); + m_engine->queueViewport(viewportRect()); + m_engine->queueClearRenderTarget(clearColor()); + m_engine->queueClearDepthStencil(1, 0, QSGD3D12Engine::ClearDepth | QSGD3D12Engine::ClearStencil); + + m_pipelineState.blend = m_freshPipelineState.blend = QSGD3D12PipelineState::BlendNone; + m_pipelineState.depthEnable = m_freshPipelineState.depthEnable = true; + m_pipelineState.depthWrite = m_freshPipelineState.depthWrite = true; + + // First do opaque... + // The algorithm is quite simple. We traverse the list back-to-front, and + // for every item we start a second traversal and draw all elements which + // have identical material. Then we clear the bit for this in the rendered + // list so we don't draw it again when we come to that index. + QBitArray rendered = m_opaqueElements; + for (int i = m_renderList.size() - 1; i >= 0; --i) { + if (rendered.testBit(i)) { + renderElement(i); + for (int j = i - 1; j >= 0; --j) { + if (rendered.testBit(j)) { + const QSGGeometryNode *gni = static_cast<QSGGeometryNode *>(m_renderList.at(i).node); + const QSGGeometryNode *gnj = static_cast<QSGGeometryNode *>(m_renderList.at(j).node); + if (gni->clipList() == gnj->clipList() + && gni->inheritedOpacity() == gnj->inheritedOpacity() + && gni->geometry()->drawingMode() == gnj->geometry()->drawingMode() + && gni->geometry()->attributes() == gnj->geometry()->attributes()) { + const QSGMaterial *ami = gni->activeMaterial(); + const QSGMaterial *amj = gnj->activeMaterial(); + if (ami->type() == amj->type() + && ami->flags() == amj->flags() + && ami->compare(amj) == 0) { + renderElement(j); + rendered.clearBit(j); + } + } + } + } + } + } + + m_pipelineState.blend = m_freshPipelineState.blend = QSGD3D12PipelineState::BlendPremul; + m_pipelineState.depthWrite = m_freshPipelineState.depthWrite = false; + + // ...then the alpha ones + for (int i = 0; i < m_renderList.size(); ++i) { + if (m_renderList.at(i).node->type() == QSGNode::GeometryNodeType && !m_opaqueElements.testBit(i)) + renderElement(i); + } +} + +void QSGD3D12Renderer::renderElement(int elementIndex) +{ + Element &e = m_renderList.at(elementIndex); + Q_ASSERT(e.node->type() == QSGNode::GeometryNodeType); + + if (e.vboOffset < 0) + return; + + Q_ASSERT(e.cboOffset >= 0); + + const QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(e.node); + if (Q_UNLIKELY(debug_render())) + qDebug() << "renderElement:" << elementIndex << gn << e.vboOffset << e.iboOffset << gn->inheritedOpacity() << gn->clipList(); + + if (gn->inheritedOpacity() < 0.001f) // pretty much invisible, don't draw it + return; + + // Update the QSGRenderer members which the materials will access. + m_current_projection_matrix = projectionMatrix(); + const float scale = 1.0 / m_renderList.size(); + m_current_projection_matrix(2, 2) = scale; + m_current_projection_matrix(2, 3) = 1.0f - (elementIndex + 1) * scale; + m_current_model_view_matrix = gn->matrix() ? *gn->matrix() : QMatrix4x4(); + m_current_determinant = m_current_model_view_matrix.determinant(); + m_current_opacity = gn->inheritedOpacity(); + + const QSGGeometry *g = gn->geometry(); + QSGD3D12Material *m = static_cast<QSGD3D12Material *>(gn->activeMaterial()); + + if (m->type() != m_lastMaterialType) { + m_pipelineState = m_freshPipelineState; + m->preparePipeline(&m_pipelineState); + } + + QSGD3D12Material::RenderState::DirtyStates dirtyState = m_nodeDirtyMap.value(e.node); + + // After a rebuild everything in the cbuffer has to be updated. + if (!e.cboPrepared) { + e.cboPrepared = true; + dirtyState = QSGD3D12Material::RenderState::DirtyAll; + } + + // DirtyMatrix does not include projection matrix changes that can arise + // due to changing the render target's size (and there is no rebuild). + // Accommodate for this. + if (m_projectionChangedDueToDeviceSize) + dirtyState |= QSGD3D12Material::RenderState::DirtyMatrix; + + quint8 *cboPtr = nullptr; + if (e.cboSize > 0) + cboPtr = m_cboData.data() + e.cboOffset; + + if (Q_UNLIKELY(debug_render())) + qDebug() << "dirty state for" << e.node << "is" << dirtyState; + + QSGD3D12Material::ExtraState extraState; + QSGD3D12Material::UpdateResults updRes = m->updatePipeline(QSGD3D12Material::makeRenderState(this, dirtyState), + &m_pipelineState, + &extraState, + cboPtr); + + if (updRes.testFlag(QSGD3D12Material::UpdatedConstantBuffer)) + m_engine->markBufferDirty(m_constantBuf, e.cboOffset, e.cboSize); + + if (updRes.testFlag(QSGD3D12Material::UpdatedBlendFactor)) + m_engine->queueSetBlendFactor(extraState.blendFactor); + + setInputLayout(g, &m_pipelineState); + + m_lastMaterialType = m->type(); + + setupClipping(gn, elementIndex); + + // ### Lines and points with sizes other than 1 have to be implemented in some other way. Just ignore for now. + if (g->drawingMode() == QSGGeometry::DrawLineStrip || g->drawingMode() == QSGGeometry::DrawLines) { + if (g->lineWidth() != 1.0f) + qWarning("QSGD3D12Renderer: Line widths other than 1 are not supported by this renderer"); + } else if (g->drawingMode() == QSGGeometry::DrawPoints) { + if (g->lineWidth() != 1.0f) + qWarning("QSGD3D12Renderer: Point sprites are not supported by this renderer"); + } + + m_engine->finalizePipeline(m_pipelineState); + + queueDrawCall(g, e); +} + +void QSGD3D12Renderer::setInputLayout(const QSGGeometry *g, QSGD3D12PipelineState *pipelineState) +{ + pipelineState->inputElements.resize(g->attributeCount()); + const QSGGeometry::Attribute *attrs = g->attributes(); + quint32 offset = 0; + for (int i = 0; i < g->attributeCount(); ++i) { + QSGD3D12InputElement &ie(pipelineState->inputElements[i]); + static const char *semanticNames[] = { "UNKNOWN", "POSITION", "COLOR", "TEXCOORD", "TEXCOORD", "TEXCOORD" }; + static const int semanticIndices[] = { 0, 0, 0, 0, 1, 2 }; + Q_ASSERT(attrs[i].semantic >= 1 && attrs[i].semantic < _countof(semanticNames)); + const int tupleSize = attrs[i].tupleSize; + ie.semanticName = semanticNames[attrs[i].semantic]; + ie.semanticIndex = semanticIndices[attrs[i].semantic]; + ie.offset = offset; + int bytesPerTuple = 0; + ie.format = QSGD3D12Engine::toDXGIFormat(QSGGeometry::Type(attrs[i].type), tupleSize, &bytesPerTuple); + if (ie.format == FmtUnknown) + qFatal("QSGD3D12Renderer: unsupported tuple size for attribute type 0x%x", attrs[i].type); + offset += bytesPerTuple; + // There is one buffer with interleaved data so the slot is always 0. + ie.slot = 0; + } +} + +void QSGD3D12Renderer::queueDrawCall(const QSGGeometry *g, const QSGD3D12Renderer::Element &e) +{ + QSGD3D12Engine::DrawParams dp; + dp.mode = QSGGeometry::DrawingMode(g->drawingMode()); + dp.vertexBuf = m_vertexBuf; + dp.constantBuf = m_constantBuf; + dp.vboOffset = e.vboOffset; + dp.vboSize = g->vertexCount() * g->sizeOfVertex(); + dp.vboStride = g->sizeOfVertex(); + dp.cboOffset = e.cboOffset; + + if (e.iboOffset >= 0) { + const QSGGeometry::Type indexType = QSGGeometry::Type(g->indexType()); + const QSGD3D12Format indexFormat = QSGD3D12Engine::toDXGIFormat(indexType); + if (indexFormat == FmtUnknown) + qFatal("QSGD3D12Renderer: unsupported index type 0x%x", indexType); + dp.count = g->indexCount(); + dp.indexBuf = m_indexBuf; + dp.startIndexIndex = e.iboOffset / e.iboStride; + dp.indexFormat = indexFormat; + } else { + dp.count = g->vertexCount(); + } + + m_engine->queueDraw(dp); +} + +void QSGD3D12Renderer::setupClipping(const QSGGeometryNode *gn, int elementIndex) +{ + const QSGClipNode *clip = gn->clipList(); + + const QRect devRect = deviceRect(); + QRect scissorRect; + enum ClipType { + ClipScissor = 0x1, + ClipStencil = 0x2 + }; + int clipTypes = 0; + quint32 stencilValue = 0; + + while (clip) { + QMatrix4x4 m = projectionMatrix(); + if (clip->matrix()) + m *= *clip->matrix(); + +#ifndef I_LIKE_STENCIL + const bool isRectangleWithNoPerspective = clip->isRectangular() + && qFuzzyIsNull(m(3, 0)) && qFuzzyIsNull(m(3, 1)); + const bool noRotate = qFuzzyIsNull(m(0, 1)) && qFuzzyIsNull(m(1, 0)); + const bool isRotate90 = qFuzzyIsNull(m(0, 0)) && qFuzzyIsNull(m(1, 1)); + + if (isRectangleWithNoPerspective && (noRotate || isRotate90)) { + QRectF bbox = clip->clipRect(); + float invW = 1.0f / m(3, 3); + float fx1, fy1, fx2, fy2; + if (noRotate) { + fx1 = (bbox.left() * m(0, 0) + m(0, 3)) * invW; + fy1 = (bbox.bottom() * m(1, 1) + m(1, 3)) * invW; + fx2 = (bbox.right() * m(0, 0) + m(0, 3)) * invW; + fy2 = (bbox.top() * m(1, 1) + m(1, 3)) * invW; + } else { + Q_ASSERT(isRotate90); + fx1 = (bbox.bottom() * m(0, 1) + m(0, 3)) * invW; + fy1 = (bbox.left() * m(1, 0) + m(1, 3)) * invW; + fx2 = (bbox.top() * m(0, 1) + m(0, 3)) * invW; + fy2 = (bbox.right() * m(1, 0) + m(1, 3)) * invW; + } + + if (fx1 > fx2) + qSwap(fx1, fx2); + if (fy1 > fy2) + qSwap(fy1, fy2); + + int ix1 = qRound((fx1 + 1) * devRect.width() * 0.5f); + int iy1 = qRound((fy1 + 1) * devRect.height() * 0.5f); + int ix2 = qRound((fx2 + 1) * devRect.width() * 0.5f); + int iy2 = qRound((fy2 + 1) * devRect.height() * 0.5f); + + if (!(clipTypes & ClipScissor)) { + scissorRect = QRect(ix1, devRect.height() - iy2, ix2 - ix1, iy2 - iy1); + clipTypes |= ClipScissor; + } else { + scissorRect &= QRect(ix1, devRect.height() - iy2, ix2 - ix1, iy2 - iy1); + } + } else +#endif + { + clipTypes |= ClipStencil; + renderStencilClip(clip, elementIndex, m, stencilValue); + } + + clip = clip->clipList(); + } + + setScissor((clipTypes & ClipScissor) ? scissorRect : viewportRect()); + + if (clipTypes & ClipStencil) { + m_pipelineState.stencilEnable = true; + m_engine->queueSetStencilRef(stencilValue); + } else { + m_pipelineState.stencilEnable = false; + } +} + +void QSGD3D12Renderer::setScissor(const QRect &r) +{ + if (m_activeScissorRect == r) + return; + + m_activeScissorRect = r; + m_engine->queueScissor(r); +} + +void QSGD3D12Renderer::renderStencilClip(const QSGClipNode *clip, int elementIndex, + const QMatrix4x4 &m, quint32 &stencilValue) +{ + QSGD3D12PipelineState sps; + sps.shaders.vs = g_VS_StencilClip; + sps.shaders.vsSize = sizeof(g_VS_StencilClip); + sps.shaders.ps = g_PS_StencilClip; + sps.shaders.psSize = sizeof(g_PS_StencilClip); + + m_engine->queueClearDepthStencil(1, 0, QSGD3D12Engine::ClearStencil); + sps.stencilEnable = true; + sps.colorWrite = false; + sps.depthWrite = false; + + sps.stencilFunc = QSGD3D12PipelineState::CompareEqual; + sps.stencilFailOp = QSGD3D12PipelineState::StencilKeep; + sps.stencilDepthFailOp = QSGD3D12PipelineState::StencilKeep; + sps.stencilPassOp = QSGD3D12PipelineState::StencilIncr; + + m_engine->queueSetStencilRef(stencilValue); + + int clipIndex = elementIndex; + while (m_renderList.at(--clipIndex).node != clip) { + Q_ASSERT(clipIndex >= 0); + } + const Element &ce = m_renderList.at(clipIndex); + Q_ASSERT(ce.node == clip); + + const QSGGeometry *g = clip->geometry(); + Q_ASSERT(g->attributeCount() == 1); + Q_ASSERT(g->attributes()[0].tupleSize == 2); + Q_ASSERT(g->attributes()[0].type == QSGGeometry::TypeFloat); + + setInputLayout(g, &sps); + m_engine->finalizePipeline(sps); + + Q_ASSERT(ce.cboSize > 0); + quint8 *p = m_cboData.data() + ce.cboOffset; + memcpy(p, m.constData(), 16 * sizeof(float)); + m_engine->markBufferDirty(m_constantBuf, ce.cboOffset, ce.cboSize); + + queueDrawCall(g, ce); + + ++stencilValue; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer_p.h new file mode 100644 index 0000000000..adb2252f80 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer_p.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12RENDERER_P_H +#define QSGD3D12RENDERER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgrenderer_p.h> +#include <QtGui/private/qdatabuffer_p.h> +#include "qsgd3d12engine_p.h" +#include "qsgd3d12material_p.h" + +QT_BEGIN_NAMESPACE + +class QSGD3D12Renderer : public QSGRenderer +{ +public: + QSGD3D12Renderer(QSGRenderContext *context); + ~QSGD3D12Renderer(); + + void renderScene(GLuint fboId) override; + void render() override; + void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override; + + void turnToLayerRenderer() { m_layerRenderer = true; } + +private: + void updateMatrices(QSGNode *node, QSGTransformNode *xform); + void updateOpacities(QSGNode *node, float inheritedOpacity); + void buildRenderList(QSGNode *node, QSGClipNode *clip); + void renderElements(); + void renderElement(int elementIndex); + void setInputLayout(const QSGGeometry *g, QSGD3D12PipelineState *pipelineState); + void setupClipping(const QSGGeometryNode *gn, int elementIndex); + void setScissor(const QRect &r); + void renderStencilClip(const QSGClipNode *clip, int elementIndex, const QMatrix4x4 &m, quint32 &stencilValue); + + struct Element { + QSGBasicGeometryNode *node = nullptr; + qint32 vboOffset = -1; + qint32 iboOffset = -1; + quint32 iboStride = 0; + qint32 cboOffset = -1; + quint32 cboSize = 0; + bool cboPrepared = false; + }; + + void queueDrawCall(const QSGGeometry *g, const Element &e); + + bool m_layerRenderer = false; + QSet<QSGNode *> m_dirtyTransformNodes; + QSet<QSGNode *> m_dirtyOpacityNodes; + QBitArray m_opaqueElements; + bool m_rebuild = true; + bool m_dirtyOpaqueElements = true; + QDataBuffer<quint8> m_vboData; + QDataBuffer<quint8> m_iboData; + QDataBuffer<quint8> m_cboData; + QDataBuffer<Element> m_renderList; + uint m_vertexBuf = 0; + uint m_indexBuf = 0; + uint m_constantBuf = 0; + QSGD3D12Engine *m_engine = nullptr; + + QSGMaterialType *m_lastMaterialType = nullptr; + QSGD3D12PipelineState m_pipelineState; + QSGD3D12PipelineState m_freshPipelineState; + + typedef QHash<QSGNode *, QSGD3D12Material::RenderState::DirtyStates> NodeDirtyMap; + NodeDirtyMap m_nodeDirtyMap; + + QRect m_activeScissorRect; + QRect m_lastDeviceRect; + bool m_projectionChangedDueToDeviceSize; + + uint m_renderTarget = 0; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12RENDERER_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp new file mode 100644 index 0000000000..a4181c7248 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop.cpp @@ -0,0 +1,1103 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12renderloop_p.h" +#include "qsgd3d12engine_p.h" +#include "qsgd3d12context_p.h" +#include "qsgd3d12rendercontext_p.h" +#include <private/qsgrenderer_p.h> +#include <private/qquickwindow_p.h> +#include <private/qquickprofiler_p.h> +#include <private/qquickanimatorcontroller_p.h> +#include <private/qquickshadereffectnode_p.h> +#include <private/qquickprofiler_p.h> +#include <private/qqmldebugserviceinterfaces_p.h> +#include <private/qqmldebugconnector_p.h> +#include <QElapsedTimer> + +QT_BEGIN_NAMESPACE + +// NOTE: Avoid categorized logging. It is slow. + +#define DECLARE_DEBUG_VAR(variable) \ + static bool debug_ ## variable() \ + { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } + +DECLARE_DEBUG_VAR(loop) +DECLARE_DEBUG_VAR(time) + +/* + The D3D render loop mostly mirrors the threaded OpenGL render loop. + + There are two classes here. QSGD3D12RenderLoop and QSGD3D12RenderThread. All + communication between the two is based on event passing and we have a number + of custom events. + + Render loop is per process, render thread is per window. The + QSGD3D12RenderContext and QSGD3D12Engine are per window as well. The former + is created (but not owned) by QQuickWindow. The D3D device is per process. + + In this implementation, the render thread is never blocked and the GUI + thread will initiate a polishAndSync which will block and wait for the + render thread to pick it up and release the block only after the render + thread is done syncing. The reason for this is: + + 1. Clear blocking paradigm. We only have one real "block" point + (polishAndSync()) and all blocking is initiated by GUI and picked up by + Render at specific times based on events. This makes the execution + deterministic. + + 2. Render does not have to interact with GUI. This is done so that the + render thread can run its own animation system which stays alive even when + the GUI thread is blocked doing I/O, object instantiation, QPainter-painting + or any other non-trivial task. + + The render thread has affinity to the GUI thread until a window is shown. + From that moment and until the window is destroyed, it will have affinity to + the render thread. (moved back at the end of run for cleanup). + */ + +// Passed from the RL to the RT when a window is removed obscured and should be +// removed from the render loop. +const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1); + +// Passed from the RL to RT when GUI has been locked, waiting for sync. +const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2); + +// Passed by the RT to itself to trigger another render pass. This is typically +// a result of QQuickWindow::update(). +const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3); + +// Passed by the RL to the RT to maybe release resource if no windows are +// rendering. +const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4); + +// Passed by the RL to the RT when a QQuickWindow::grabWindow() is called. +const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 5); + +// Passed by the window when there is a render job to run. +const QEvent::Type WM_PostJob = QEvent::Type(QEvent::User + 6); + +class QSGD3D12WindowEvent : public QEvent +{ +public: + QSGD3D12WindowEvent(QQuickWindow *c, QEvent::Type type) : QEvent(type), window(c) { } + QQuickWindow *window; +}; + +class QSGD3D12TryReleaseEvent : public QSGD3D12WindowEvent +{ +public: + QSGD3D12TryReleaseEvent(QQuickWindow *win, bool destroy) + : QSGD3D12WindowEvent(win, WM_TryRelease), destroying(destroy) { } + bool destroying; +}; + +class QSGD3D12SyncEvent : public QSGD3D12WindowEvent +{ +public: + QSGD3D12SyncEvent(QQuickWindow *c, bool inExpose, bool force) + : QSGD3D12WindowEvent(c, WM_RequestSync) + , size(c->size()) + , dpr(c->effectiveDevicePixelRatio()) + , syncInExpose(inExpose) + , forceRenderPass(force) { } + QSize size; + float dpr; + bool syncInExpose; + bool forceRenderPass; +}; + +class QSGD3D12GrabEvent : public QSGD3D12WindowEvent +{ +public: + QSGD3D12GrabEvent(QQuickWindow *c, QImage *result) + : QSGD3D12WindowEvent(c, WM_Grab), image(result) { } + QImage *image; +}; + +class QSGD3D12JobEvent : public QSGD3D12WindowEvent +{ +public: + QSGD3D12JobEvent(QQuickWindow *c, QRunnable *postedJob) + : QSGD3D12WindowEvent(c, WM_PostJob), job(postedJob) { } + ~QSGD3D12JobEvent() { delete job; } + QRunnable *job; +}; + +class QSGD3D12EventQueue : public QQueue<QEvent *> +{ +public: + void addEvent(QEvent *e) { + mutex.lock(); + enqueue(e); + if (waiting) + condition.wakeOne(); + mutex.unlock(); + } + + QEvent *takeEvent(bool wait) { + mutex.lock(); + if (isEmpty() && wait) { + waiting = true; + condition.wait(&mutex); + waiting = false; + } + QEvent *e = dequeue(); + mutex.unlock(); + return e; + } + + bool hasMoreEvents() { + mutex.lock(); + bool has = !isEmpty(); + mutex.unlock(); + return has; + } + +private: + QMutex mutex; + QWaitCondition condition; + bool waiting = false; +}; + +static inline int qsgrl_animation_interval() +{ + const qreal refreshRate = QGuiApplication::primaryScreen() ? QGuiApplication::primaryScreen()->refreshRate() : 0; + return refreshRate < 1 ? 16 : int(1000 / refreshRate); +} + +class QSGD3D12RenderThread : public QThread +{ + Q_OBJECT + +public: + QSGD3D12RenderThread(QSGD3D12RenderLoop *rl, QSGRenderContext *renderContext) + : renderLoop(rl) + { + rc = static_cast<QSGD3D12RenderContext *>(renderContext); + vsyncDelta = qsgrl_animation_interval(); + } + + ~QSGD3D12RenderThread() + { + delete rc; + } + + bool event(QEvent *e); + void run(); + + void syncAndRender(); + void sync(bool inExpose); + + void requestRepaint() + { + if (sleeping) + stopEventProcessing = true; + if (exposedWindow) + pendingUpdate |= RepaintRequest; + } + + void processEventsAndWaitForMore(); + void processEvents(); + void postEvent(QEvent *e); + + enum UpdateRequest { + SyncRequest = 0x01, + RepaintRequest = 0x02, + ExposeRequest = 0x04 | RepaintRequest | SyncRequest + }; + + QSGD3D12Engine *engine = nullptr; + QSGD3D12RenderLoop *renderLoop; + QSGD3D12RenderContext *rc; + QAnimationDriver *rtAnim = nullptr; + volatile bool active = false; + uint pendingUpdate = 0; + bool sleeping = false; + bool syncResultedInChanges = false; + float vsyncDelta; + QMutex mutex; + QWaitCondition waitCondition; + QQuickWindow *exposedWindow = nullptr; + bool stopEventProcessing = false; + QSGD3D12EventQueue eventQueue; + QElapsedTimer threadTimer; + qint64 syncTime; + qint64 renderTime; + qint64 sinceLastTime; + +public slots: + void onSceneGraphChanged() { + syncResultedInChanges = true; + } +}; + +bool QSGD3D12RenderThread::event(QEvent *e) +{ + switch (e->type()) { + + case WM_Obscure: + Q_ASSERT(!exposedWindow || exposedWindow == static_cast<QSGD3D12WindowEvent *>(e)->window); + if (Q_UNLIKELY(debug_loop())) + qDebug() << "RT - WM_Obscure" << exposedWindow; + mutex.lock(); + if (exposedWindow) { + QQuickWindowPrivate::get(exposedWindow)->fireAboutToStop(); + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_Obscure - window removed"); + exposedWindow = nullptr; + } + waitCondition.wakeOne(); + mutex.unlock(); + return true; + + case WM_RequestSync: { + QSGD3D12SyncEvent *wme = static_cast<QSGD3D12SyncEvent *>(e); + if (sleeping) + stopEventProcessing = true; + if (!engine->window()) { + const int samples = wme->window->format().samples(); + if (Q_UNLIKELY(debug_loop())) + qDebug() << "RT - WM_RequestSync - initializing D3D12 engine" << wme->window + << wme->size << wme->dpr << samples; + engine->attachToWindow(wme->window->winId(), wme->size, wme->dpr, samples); + } + exposedWindow = wme->window; + Q_ASSERT(exposedWindow->winId() == engine->window()); // one thread+engine for each window + engine->setWindowSize(wme->size, wme->dpr); + if (Q_UNLIKELY(debug_loop())) + qDebug() << "RT - WM_RequestSync" << exposedWindow; + pendingUpdate |= SyncRequest; + if (wme->syncInExpose) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_RequestSync - triggered from expose"); + pendingUpdate |= ExposeRequest; + } + if (wme->forceRenderPass) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_RequestSync - repaint regardless"); + pendingUpdate |= RepaintRequest; + } + return true; + } + + case WM_TryRelease: { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_TryRelease"); + mutex.lock(); + renderLoop->lockedForSync = true; + QSGD3D12TryReleaseEvent *wme = static_cast<QSGD3D12TryReleaseEvent *>(e); + // Only when no windows are exposed anymore or we are shutting down. + if (!exposedWindow || wme->destroying) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_TryRelease - invalidating rc"); + if (wme->window) { + QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window); + QQuickShaderEffectMaterial::cleanupMaterialCache(); + if (wme->destroying) + wd->cleanupNodesOnShutdown(); + rc->invalidate(); + QCoreApplication::processEvents(); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + if (wme->destroying) + delete wd->animationController; + } + if (wme->destroying) + active = false; + if (sleeping) + stopEventProcessing = true; + } else { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_TryRelease - not releasing because window is still active"); + } + waitCondition.wakeOne(); + renderLoop->lockedForSync = false; + mutex.unlock(); + return true; + } + + case WM_Grab: { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_Grab"); + QSGD3D12GrabEvent *wme = static_cast<QSGD3D12GrabEvent *>(e); + Q_ASSERT(wme->window); + Q_ASSERT(wme->window == exposedWindow || !exposedWindow); + mutex.lock(); + if (wme->window) { + // ### + Q_UNREACHABLE(); + } + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_Grab - waking gui to handle result"); + waitCondition.wakeOne(); + mutex.unlock(); + return true; + } + + case WM_PostJob: { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_PostJob"); + QSGD3D12JobEvent *wme = static_cast<QSGD3D12JobEvent *>(e); + Q_ASSERT(wme->window == exposedWindow); + if (exposedWindow) { + wme->job->run(); + delete wme->job; + wme->job = nullptr; + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_PostJob - job done"); + } + return true; + } + + case WM_RequestRepaint: + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - WM_RequestPaint"); + // When GUI posts this event, it is followed by a polishAndSync, so we + // must not exit the event loop yet. + pendingUpdate |= RepaintRequest; + break; + + default: + break; + } + + return QThread::event(e); +} + +void QSGD3D12RenderThread::postEvent(QEvent *e) +{ + eventQueue.addEvent(e); +} + +void QSGD3D12RenderThread::processEvents() +{ + while (eventQueue.hasMoreEvents()) { + QEvent *e = eventQueue.takeEvent(false); + event(e); + delete e; + } +} + +void QSGD3D12RenderThread::processEventsAndWaitForMore() +{ + stopEventProcessing = false; + while (!stopEventProcessing) { + QEvent *e = eventQueue.takeEvent(true); + event(e); + delete e; + } +} + +void QSGD3D12RenderThread::run() +{ + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - run()"); + + engine = new QSGD3D12Engine; + rc->setEngine(engine); + + rtAnim = rc->sceneGraphContext()->createAnimationDriver(nullptr); + rtAnim->install(); + + if (QQmlDebugConnector::service<QQmlProfilerService>()) + QQuickProfiler::registerAnimationCallback(); + + while (active) { + if (exposedWindow) + syncAndRender(); + + processEvents(); + QCoreApplication::processEvents(); + + if (pendingUpdate == 0 || !exposedWindow) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - done drawing, sleep"); + sleeping = true; + processEventsAndWaitForMore(); + sleeping = false; + } + } + + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - run() exiting"); + + delete rtAnim; + rtAnim = nullptr; + + rc->moveToThread(renderLoop->thread()); + moveToThread(renderLoop->thread()); + + rc->setEngine(nullptr); + delete engine; + engine = nullptr; +} + +void QSGD3D12RenderThread::sync(bool inExpose) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - sync"); + + mutex.lock(); + Q_ASSERT_X(renderLoop->lockedForSync, "QSGD3D12RenderThread::sync()", "sync triggered with gui not locked"); + + // Recover from device loss. + if (!engine->hasResources()) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - sync - device was lost, resetting scenegraph"); + QQuickWindowPrivate::get(exposedWindow)->cleanupNodesOnShutdown(); + rc->invalidate(); + } + + if (engine->window()) { + QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow); + bool hadRenderer = wd->renderer != nullptr; + // If the scene graph was touched since the last sync() make sure it sends the + // changed signal. + if (wd->renderer) + wd->renderer->clearChangedFlag(); + + wd->syncSceneGraph(); + + if (!hadRenderer && wd->renderer) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - created renderer"); + syncResultedInChanges = true; + connect(wd->renderer, &QSGRenderer::sceneGraphChanged, this, + &QSGD3D12RenderThread::onSceneGraphChanged, Qt::DirectConnection); + } + + // Process deferred deletes now, directly after the sync as deleteLater + // on the GUI must now also have resulted in SG changes and the delete + // is a safe operation. + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + } + + if (!inExpose) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - sync complete, waking gui"); + waitCondition.wakeOne(); + mutex.unlock(); + } +} + +void QSGD3D12RenderThread::syncAndRender() +{ + bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled(); + if (profileFrames) { + sinceLastTime = threadTimer.nsecsElapsed(); + threadTimer.start(); + } + Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame); + + QElapsedTimer waitTimer; + waitTimer.start(); + + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - syncAndRender()"); + + syncResultedInChanges = false; + QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow); + + const bool repaintRequested = (pendingUpdate & RepaintRequest) || wd->customRenderStage; + const bool syncRequested = pendingUpdate & SyncRequest; + const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest; + pendingUpdate = 0; + + if (syncRequested) + sync(exposeRequested); + +#ifndef QSG_NO_RENDER_TIMING + if (profileFrames) + syncTime = threadTimer.nsecsElapsed(); +#endif + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); + + if (!syncResultedInChanges && !repaintRequested) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - no changes, render aborted"); + int waitTime = vsyncDelta - (int) waitTimer.elapsed(); + if (waitTime > 0) + msleep(waitTime); + return; + } + + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - rendering started"); + + if (rtAnim->isRunning()) { + wd->animationController->lock(); + rtAnim->advance(); + wd->animationController->unlock(); + } + + bool canRender = wd->renderer != nullptr; + // Recover from device loss. + if (!engine->hasResources()) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - syncAndRender - device was lost, posting FullUpdateRequest"); + // Cannot do anything here because gui is not locked. Request a new + // sync+render round on the gui thread and let the sync handle it. + QCoreApplication::postEvent(exposedWindow, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))); + canRender = false; + } + + if (canRender) { + wd->renderSceneGraph(engine->windowSize()); + if (profileFrames) + renderTime = threadTimer.nsecsElapsed(); + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); + + // The engine is able to have multiple frames in flight. This in effect is + // similar to BufferQueueingOpenGL. Provide an env var to force the + // traditional blocking swap behavior, just in case. + static bool blockOnEachFrame = qEnvironmentVariableIntValue("QT_D3D_BLOCKING_PRESENT") != 0; + + if (!wd->customRenderStage || !wd->customRenderStage->swap()) + engine->present(); + + if (blockOnEachFrame) + engine->waitGPU(); + + // The concept of "frame swaps" is quite misleading by default, when + // blockOnEachFrame is not used, but emit it for compatibility. + wd->fireFrameSwapped(); + } else { + Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame, 1); + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - window not ready, skipping render"); + } + + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - rendering done"); + + if (exposeRequested) { + if (Q_UNLIKELY(debug_loop())) + qDebug("RT - wake gui after initial expose"); + waitCondition.wakeOne(); + mutex.unlock(); + } + + if (Q_UNLIKELY(debug_time())) + qDebug("Frame rendered with 'd3d12' renderloop in %dms, sync=%d, render=%d, swap=%d - (on render thread)", + int(threadTimer.elapsed()), + int((syncTime/1000000)), + int((renderTime - syncTime) / 1000000), + int(threadTimer.elapsed() - renderTime / 1000000)); + + Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame); +} + +template<class T> T *windowFor(const QVector<T> &list, QQuickWindow *window) +{ + for (const T &t : list) { + if (t.window == window) + return const_cast<T *>(&t); + } + return nullptr; +} + +QSGD3D12RenderLoop::QSGD3D12RenderLoop() +{ + if (Q_UNLIKELY(debug_loop())) + qDebug("new d3d12 render loop ctor"); + + sg = new QSGD3D12Context; + + anim = sg->createAnimationDriver(this); + connect(anim, &QAnimationDriver::started, this, &QSGD3D12RenderLoop::onAnimationStarted); + connect(anim, &QAnimationDriver::stopped, this, &QSGD3D12RenderLoop::onAnimationStopped); + anim->install(); +} + +QSGD3D12RenderLoop::~QSGD3D12RenderLoop() +{ + if (Q_UNLIKELY(debug_loop())) + qDebug("new d3d12 render loop dtor"); + + delete sg; +} + +void QSGD3D12RenderLoop::show(QQuickWindow *window) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "show" << window; +} + +void QSGD3D12RenderLoop::hide(QQuickWindow *window) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "hide" << window; + + if (window->isExposed()) + handleObscurity(windowFor(windows, window)); + + releaseResources(window); +} + +void QSGD3D12RenderLoop::resize(QQuickWindow *window) +{ + if (!window->isExposed() || window->size().isEmpty()) + return; + + if (Q_UNLIKELY(debug_loop())) + qDebug() << "resize" << window << window->size(); +} + +void QSGD3D12RenderLoop::windowDestroyed(QQuickWindow *window) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "window destroyed" << window; + + WindowData *w = windowFor(windows, window); + if (!w) + return; + + handleObscurity(w); + handleResourceRelease(w, true); + + QSGD3D12RenderThread *thread = w->thread; + while (thread->isRunning()) + QThread::yieldCurrentThread(); + + Q_ASSERT(thread->thread() == QThread::currentThread()); + delete thread; + + for (int i = 0; i < windows.size(); ++i) { + if (windows.at(i).window == window) { + windows.removeAt(i); + break; + } + } +} + +void QSGD3D12RenderLoop::exposureChanged(QQuickWindow *window) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "exposure changed" << window; + + if (window->isExposed()) { + handleExposure(window); + } else { + WindowData *w = windowFor(windows, window); + if (w) + handleObscurity(w); + } +} + +QImage QSGD3D12RenderLoop::grab(QQuickWindow *window) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "grab" << window; + + WindowData *w = windowFor(windows, window); + Q_ASSERT(w); + + if (!w->thread->isRunning()) + return QImage(); + + if (!window->handle()) + window->create(); + + QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); + wd->polishItems(); + + QImage result; + w->thread->mutex.lock(); + lockedForSync = true; + w->thread->postEvent(new QSGD3D12GrabEvent(window, &result)); + w->thread->waitCondition.wait(&w->thread->mutex); + lockedForSync = false; + w->thread->mutex.unlock(); + + return result; +} + +void QSGD3D12RenderLoop::update(QQuickWindow *window) +{ + WindowData *w = windowFor(windows, window); + if (!w) + return; + + if (w->thread == QThread::currentThread()) { + w->thread->requestRepaint(); + return; + } + + // We set forceRenderPass because we want to make sure the QQuickWindow + // actually does a full render pass after the next sync. + w->forceRenderPass = true; + scheduleUpdate(w); +} + +void QSGD3D12RenderLoop::maybeUpdate(QQuickWindow *window) +{ + WindowData *w = windowFor(windows, window); + if (w) + scheduleUpdate(w); +} + +// called in response to window->requestUpdate() +void QSGD3D12RenderLoop::handleUpdateRequest(QQuickWindow *window) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "handleUpdateRequest" << window; + + WindowData *w = windowFor(windows, window); + if (w) + polishAndSync(w, false); +} + +QAnimationDriver *QSGD3D12RenderLoop::animationDriver() const +{ + return anim; +} + +QSGContext *QSGD3D12RenderLoop::sceneGraphContext() const +{ + return sg; +} + +QSGRenderContext *QSGD3D12RenderLoop::createRenderContext(QSGContext *) const +{ + return sg->createRenderContext(); +} + +void QSGD3D12RenderLoop::releaseResources(QQuickWindow *window) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "releaseResources" << window; + + WindowData *w = windowFor(windows, window); + if (w) + handleResourceRelease(w, false); +} + +void QSGD3D12RenderLoop::postJob(QQuickWindow *window, QRunnable *job) +{ + WindowData *w = windowFor(windows, window); + if (w && w->thread && w->thread->exposedWindow) + w->thread->postEvent(new QSGD3D12JobEvent(window, job)); + else + delete job; +} + +QSurface::SurfaceType QSGD3D12RenderLoop::windowSurfaceType() const +{ + return QSurface::OpenGLSurface; +} + +bool QSGD3D12RenderLoop::interleaveIncubation() const +{ + bool somethingVisible = false; + for (const WindowData &w : windows) { + if (w.window->isVisible() && w.window->isExposed()) { + somethingVisible = true; + break; + } + } + return somethingVisible && anim->isRunning(); +} + +bool QSGD3D12RenderLoop::event(QEvent *e) +{ + if (e->type() == QEvent::Timer) { + QTimerEvent *te = static_cast<QTimerEvent *>(e); + if (te->timerId() == animationTimer) { + anim->advance(); + emit timeToIncubate(); + return true; + } + } + + return QObject::event(e); +} + +void QSGD3D12RenderLoop::onAnimationStarted() +{ + startOrStopAnimationTimer(); + + for (const WindowData &w : qAsConst(windows)) + w.window->requestUpdate(); +} + +void QSGD3D12RenderLoop::onAnimationStopped() +{ + startOrStopAnimationTimer(); +} + +void QSGD3D12RenderLoop::startOrStopAnimationTimer() +{ + int exposedWindowCount = 0; + const WindowData *exposed = nullptr; + + for (int i = 0; i < windows.size(); ++i) { + const WindowData &w(windows[i]); + if (w.window->isVisible() && w.window->isExposed()) { + ++exposedWindowCount; + exposed = &w; + } + } + + if (animationTimer && (exposedWindowCount == 1 || !anim->isRunning())) { + killTimer(animationTimer); + animationTimer = 0; + // If animations are running, make sure we keep on animating + if (anim->isRunning()) + exposed->window->requestUpdate(); + } else if (!animationTimer && exposedWindowCount != 1 && anim->isRunning()) { + animationTimer = startTimer(qsgrl_animation_interval()); + } +} + +void QSGD3D12RenderLoop::handleExposure(QQuickWindow *window) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "handleExposure" << window; + + WindowData *w = windowFor(windows, window); + if (!w) { + if (Q_UNLIKELY(debug_loop())) + qDebug("adding window to list"); + WindowData win; + win.window = window; + QSGRenderContext *rc = QQuickWindowPrivate::get(window)->context; // will transfer ownership + win.thread = new QSGD3D12RenderThread(this, rc); + win.updateDuringSync = false; + win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt + windows.append(win); + w = &windows.last(); + } + + // set this early as we'll be rendering shortly anyway and this avoids + // special casing exposure in polishAndSync. + w->thread->exposedWindow = window; + + if (w->window->size().isEmpty() + || (w->window->isTopLevel() && !w->window->geometry().intersects(w->window->screen()->availableGeometry()))) { +#ifndef QT_NO_DEBUG + qWarning().noquote().nospace() << "QSGD3D12RenderLoop: expose event received for window " + << w->window << " with invalid geometry: " << w->window->geometry() + << " on " << w->window->screen(); +#endif + } + + if (!w->window->handle()) + w->window->create(); + + // Start render thread if it is not running + if (!w->thread->isRunning()) { + if (Q_UNLIKELY(debug_loop())) + qDebug("starting render thread"); + // Push a few things to the render thread. + QQuickAnimatorController *controller = QQuickWindowPrivate::get(w->window)->animationController; + if (controller->thread() != w->thread) + controller->moveToThread(w->thread); + if (w->thread->thread() == QThread::currentThread()) { + w->thread->rc->moveToThread(w->thread); + w->thread->moveToThread(w->thread); + } + + w->thread->active = true; + w->thread->start(); + + if (!w->thread->isRunning()) + qFatal("Render thread failed to start, aborting application."); + } + + polishAndSync(w, true); + + startOrStopAnimationTimer(); +} + +void QSGD3D12RenderLoop::handleObscurity(WindowData *w) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "handleObscurity" << w->window; + + if (w->thread->isRunning()) { + w->thread->mutex.lock(); + w->thread->postEvent(new QSGD3D12WindowEvent(w->window, WM_Obscure)); + w->thread->waitCondition.wait(&w->thread->mutex); + w->thread->mutex.unlock(); + } + + startOrStopAnimationTimer(); +} + +void QSGD3D12RenderLoop::scheduleUpdate(WindowData *w) +{ + if (!QCoreApplication::instance()) + return; + + if (!w || !w->thread->isRunning()) + return; + + QThread *current = QThread::currentThread(); + if (current != QCoreApplication::instance()->thread() && (current != w->thread || !lockedForSync)) { + qWarning() << "Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()"; + return; + } + + if (current == w->thread) { + w->updateDuringSync = true; + return; + } + + w->window->requestUpdate(); +} + +void QSGD3D12RenderLoop::handleResourceRelease(WindowData *w, bool destroying) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "handleResourceRelease" << (destroying ? "destroying" : "hide/releaseResources") << w->window; + + w->thread->mutex.lock(); + if (w->thread->isRunning() && w->thread->active) { + QQuickWindow *window = w->window; + + // Note that window->handle() is typically null by this time because + // the platform window is already destroyed. This should not be a + // problem for the D3D cleanup. + + w->thread->postEvent(new QSGD3D12TryReleaseEvent(window, destroying)); + w->thread->waitCondition.wait(&w->thread->mutex); + + // Avoid a shutdown race condition. + // If SG is invalidated and 'active' becomes false, the thread's run() + // method will exit. handleExposure() relies on QThread::isRunning() (because it + // potentially needs to start the thread again) and our mutex cannot be used to + // track the thread stopping, so we wait a few nanoseconds extra so the thread + // can exit properly. + if (!w->thread->active) + w->thread->wait(); + } + w->thread->mutex.unlock(); +} + +void QSGD3D12RenderLoop::polishAndSync(WindowData *w, bool inExpose) +{ + if (Q_UNLIKELY(debug_loop())) + qDebug() << "polishAndSync" << (inExpose ? "(in expose)" : "(normal)") << w->window; + + QQuickWindow *window = w->window; + if (!w->thread || !w->thread->exposedWindow) { + if (Q_UNLIKELY(debug_loop())) + qDebug("polishAndSync - not exposed, abort"); + return; + } + + // Flush pending touch events. + QQuickWindowPrivate::get(window)->flushDelayedTouchEvent(); + // The delivery of the event might have caused the window to stop rendering + w = windowFor(windows, window); + if (!w || !w->thread || !w->thread->exposedWindow) { + if (Q_UNLIKELY(debug_loop())) + qDebug("polishAndSync - removed after touch event flushing, abort"); + return; + } + + QElapsedTimer timer; + qint64 polishTime = 0; + qint64 waitTime = 0; + qint64 syncTime = 0; + bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled(); + if (profileFrames) + timer.start(); + Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync); + + QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); + wd->polishItems(); + + if (profileFrames) + polishTime = timer.nsecsElapsed(); + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync); + + w->updateDuringSync = false; + + emit window->afterAnimating(); + + if (Q_UNLIKELY(debug_loop())) + qDebug("polishAndSync - lock for sync"); + w->thread->mutex.lock(); + lockedForSync = true; + w->thread->postEvent(new QSGD3D12SyncEvent(window, inExpose, w->forceRenderPass)); + w->forceRenderPass = false; + + if (Q_UNLIKELY(debug_loop())) + qDebug("polishAndSync - wait for sync"); + if (profileFrames) + waitTime = timer.nsecsElapsed(); + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync); + w->thread->waitCondition.wait(&w->thread->mutex); + lockedForSync = false; + w->thread->mutex.unlock(); + if (Q_UNLIKELY(debug_loop())) + qDebug("polishAndSync - unlock after sync"); + + if (profileFrames) + syncTime = timer.nsecsElapsed(); + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync); + + if (!animationTimer && anim->isRunning()) { + if (Q_UNLIKELY(debug_loop())) + qDebug("polishAndSync - advancing animations"); + anim->advance(); + // We need to trigger another sync to keep animations running... + w->window->requestUpdate(); + emit timeToIncubate(); + } else if (w->updateDuringSync) { + w->window->requestUpdate(); + } + + if (Q_UNLIKELY(debug_time())) + qDebug().nospace() + << "Frame prepared with 'd3d12' renderloop" + << ", polish=" << (polishTime / 1000000) + << ", lock=" << (waitTime - polishTime) / 1000000 + << ", blockedForSync=" << (syncTime - waitTime) / 1000000 + << ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000 + << " - (on gui thread) " << window; + + Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync); +} + +#include "qsgd3d12renderloop.moc" + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop_p.h new file mode 100644 index 0000000000..56dcb1d490 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderloop_p.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12RENDERLOOP_P_H +#define QSGD3D12RENDERLOOP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgrenderloop_p.h> + +QT_BEGIN_NAMESPACE + +class QSGD3D12Engine; +class QSGD3D12Context; +class QSGD3D12RenderContext; +class QSGD3D12RenderThread; + +class QSGD3D12RenderLoop : public QSGRenderLoop +{ + Q_OBJECT + +public: + QSGD3D12RenderLoop(); + ~QSGD3D12RenderLoop(); + + void show(QQuickWindow *window) override; + void hide(QQuickWindow *window) override; + void resize(QQuickWindow *window) override; + + void windowDestroyed(QQuickWindow *window) override; + + void exposureChanged(QQuickWindow *window) override; + + QImage grab(QQuickWindow *window) override; + + void update(QQuickWindow *window) override; + void maybeUpdate(QQuickWindow *window) override; + void handleUpdateRequest(QQuickWindow *window) override; + + QAnimationDriver *animationDriver() const override; + + QSGContext *sceneGraphContext() const override; + QSGRenderContext *createRenderContext(QSGContext *) const override; + + void releaseResources(QQuickWindow *window) override; + void postJob(QQuickWindow *window, QRunnable *job) override; + + QSurface::SurfaceType windowSurfaceType() const override; + + bool interleaveIncubation() const override; + + bool event(QEvent *e) override; + +public Q_SLOTS: + void onAnimationStarted(); + void onAnimationStopped(); + +private: + struct WindowData { + QQuickWindow *window; + QSGD3D12RenderThread *thread; + uint updateDuringSync : 1; + uint forceRenderPass : 1; + }; + + void startOrStopAnimationTimer(); + void handleExposure(QQuickWindow *window); + void handleObscurity(WindowData *w); + void scheduleUpdate(WindowData *w); + void handleResourceRelease(WindowData *w, bool destroying); + void polishAndSync(WindowData *w, bool inExpose); + + QSGD3D12Context *sg; + QAnimationDriver *anim; + int animationTimer = 0; + bool lockedForSync = false; + QVector<WindowData> windows; + + friend class QSGD3D12RenderThread; +}; + +QT_END_NAMESPACE + +#endif // QSGD3D12RENDERLOOP_P_H diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp new file mode 100644 index 0000000000..0250023fdf --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgd3d12texture_p.h" +#include "qsgd3d12engine_p.h" +#include <private/qsgcontext_p.h> + +QT_BEGIN_NAMESPACE + +void QSGD3D12Texture::setImage(const QImage &image, uint flags) +{ + // ### atlas? + + const bool alphaRequest = flags & QSGRenderContext::CreateTexture_Alpha; + m_alphaWanted = alphaRequest && image.hasAlphaChannel(); + + m_image = image; + m_size = image.size(); + + m_id = m_engine->genTexture(); + Q_ASSERT(m_id); + + // We could kick off the texture creation and the async upload right here. + // Unfortunately we cannot tell at this stage if mipmaps will be enabled + // via an Image element's mipmap property...so defer to bind(). + m_createPending = true; +} + +QSGD3D12Texture::~QSGD3D12Texture() +{ + if (m_id) + m_engine->releaseTexture(m_id); +} + +int QSGD3D12Texture::textureId() const +{ + return m_id; +} + +QSize QSGD3D12Texture::textureSize() const +{ + return m_size; +} + +bool QSGD3D12Texture::hasAlphaChannel() const +{ + return m_alphaWanted; +} + +bool QSGD3D12Texture::hasMipmaps() const +{ + return mipmapFiltering() != QSGTexture::None; +} + +QRectF QSGD3D12Texture::normalizedTextureSubRect() const +{ + return QRectF(0, 0, 1, 1); +} + +void QSGD3D12Texture::bind() +{ + // Called when the texture material updates the pipeline state. + + if (!m_createPending && hasMipmaps() != m_createdWithMipMaps) { + m_engine->releaseTexture(m_id); + m_id = m_engine->genTexture(); + Q_ASSERT(m_id); + m_createPending = true; + } + + if (m_createPending) { + m_createPending = false; + + QSGD3D12Engine::TextureCreateFlags createFlags = 0; + if (m_alphaWanted) + createFlags |= QSGD3D12Engine::CreateWithAlpha; + + m_createdWithMipMaps = hasMipmaps(); + if (m_createdWithMipMaps) + createFlags |= QSGD3D12Engine::CreateWithMipMaps; + + m_engine->createTexture(m_id, m_image.size(), m_image.format(), createFlags); + m_engine->queueTextureUpload(m_id, m_image); + } + + // Here we know that the texture is going to be used in the current frame + // by the next draw call. Notify the engine so that it can wait for + // possible pending uploads and set up the pipeline accordingly. + m_engine->activateTexture(m_id); +} + +SIZE_T QSGD3D12Texture::srv() const +{ + Q_ASSERT(m_id); + return m_engine->textureSRV(m_id); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h new file mode 100644 index 0000000000..b9d53dd1e6 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGD3D12TEXTURE_P_H +#define QSGD3D12TEXTURE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qsgtexture.h> +#include <basetsd.h> + +QT_BEGIN_NAMESPACE + +class QSGD3D12Engine; + +class QSGD3D12Texture : public QSGTexture +{ +public: + QSGD3D12Texture(QSGD3D12Engine *engine) : m_engine(engine) { } + ~QSGD3D12Texture(); + + void setImage(const QImage &image, uint flags); + + int textureId() const override; + QSize textureSize() const override; + bool hasAlphaChannel() const override; + bool hasMipmaps() const override; + QRectF normalizedTextureSubRect() const override; + void bind() override; + + SIZE_T srv() const; + +private: + QSGD3D12Engine *m_engine; + QImage m_image; + bool m_createPending = false; + bool m_createdWithMipMaps = false; + uint m_id = 0; + bool m_alphaWanted = false; + QSize m_size; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/mipmapgen.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/mipmapgen.hlsl new file mode 100644 index 0000000000..6793b534b0 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/shaders/mipmapgen.hlsl @@ -0,0 +1,60 @@ +static const uint GROUP_DIM = 8; // 2 ^ (out_mip_count - 1) + +Texture2D tex : register(t0); +SamplerState samp : register(s0); + +cbuffer ConstantBuffer : register(b0) +{ + uint2 mip1Size; + uint sampleLevel; + uint totalMips; +} + +RWTexture2D<float4> mip1 : register(u0); +RWTexture2D<float4> mip2 : register(u1); +RWTexture2D<float4> mip3 : register(u2); +RWTexture2D<float4> mip4 : register(u3); + +groupshared float4 groupColor[GROUP_DIM][GROUP_DIM]; + +[numthreads(GROUP_DIM, GROUP_DIM, 1)] +void CS_Generate4MipMaps(uint3 localId: SV_GroupThreadId, uint3 globalId: SV_DispatchThreadID) +{ + const float2 coord = float2(1.0f / float(mip1Size.x), 1.0f / float(mip1Size.y)) * (globalId.xy + 0.5); + float4 c = tex.SampleLevel(samp, coord, sampleLevel); + + mip1[globalId.xy] = c; + groupColor[localId.y][localId.x] = c; + + if (sampleLevel + 1 >= totalMips) + return; + + GroupMemoryBarrierWithGroupSync(); + + if ((localId.x & 1) == 0 && (localId.y & 1) == 0) { + c = (c + groupColor[localId.y][localId.x + 1] + groupColor[localId.y + 1][localId.x] + groupColor[localId.y + 1][localId.x + 1]) / 4.0; + mip2[globalId.xy / 2] = c; + groupColor[localId.y][localId.x] = c; + } + + if (sampleLevel + 2 >= totalMips) + return; + + GroupMemoryBarrierWithGroupSync(); + + if ((localId.x & 3) == 0 && (localId.y & 3) == 0) { + c = (c + groupColor[localId.y][localId.x + 2] + groupColor[localId.y + 2][localId.x] + groupColor[localId.y + 2][localId.x + 2]) / 4.0; + mip3[globalId.xy / 4] = c; + groupColor[localId.y][localId.x] = c; + } + + if (sampleLevel + 3 >= totalMips) + return; + + GroupMemoryBarrierWithGroupSync(); + + if ((localId.x & 7) == 0 && (localId.y & 7) == 0) { + c = (c + groupColor[localId.y][localId.x + 3] + groupColor[localId.y + 3][localId.x] + groupColor[localId.y + 3][localId.x + 3]) / 4.0; + mip4[globalId.xy / 8] = c; + } +} diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri b/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri new file mode 100644 index 0000000000..02786e2606 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/shaders/shaders.pri @@ -0,0 +1,101 @@ +vertexcolor_VSPS = $$PWD/vertexcolor.hlsl +vertexcolor_vshader.input = vertexcolor_VSPS +vertexcolor_vshader.header = vs_vertexcolor.hlslh +vertexcolor_vshader.entry = VS_VertexColor +vertexcolor_vshader.type = vs_5_0 +vertexcolor_pshader.input = vertexcolor_VSPS +vertexcolor_pshader.header = ps_vertexcolor.hlslh +vertexcolor_pshader.entry = PS_VertexColor +vertexcolor_pshader.type = ps_5_0 + +stencilclip_VSPS = $$PWD/stencilclip.hlsl +stencilclip_vshader.input = stencilclip_VSPS +stencilclip_vshader.header = vs_stencilclip.hlslh +stencilclip_vshader.entry = VS_StencilClip +stencilclip_vshader.type = vs_5_0 +stencilclip_pshader.input = stencilclip_VSPS +stencilclip_pshader.header = ps_stencilclip.hlslh +stencilclip_pshader.entry = PS_StencilClip +stencilclip_pshader.type = ps_5_0 + +smoothcolor_VSPS = $$PWD/smoothcolor.hlsl +smoothcolor_vshader.input = smoothcolor_VSPS +smoothcolor_vshader.header = vs_smoothcolor.hlslh +smoothcolor_vshader.entry = VS_SmoothColor +smoothcolor_vshader.type = vs_5_0 +smoothcolor_pshader.input = smoothcolor_VSPS +smoothcolor_pshader.header = ps_smoothcolor.hlslh +smoothcolor_pshader.entry = PS_SmoothColor +smoothcolor_pshader.type = ps_5_0 + +texture_VSPS = $$PWD/texture.hlsl +texture_vshader.input = texture_VSPS +texture_vshader.header = vs_texture.hlslh +texture_vshader.entry = VS_Texture +texture_vshader.type = vs_5_0 +texture_pshader.input = texture_VSPS +texture_pshader.header = ps_texture.hlslh +texture_pshader.entry = PS_Texture +texture_pshader.type = ps_5_0 + +smoothtexture_VSPS = $$PWD/smoothtexture.hlsl +smoothtexture_vshader.input = smoothtexture_VSPS +smoothtexture_vshader.header = vs_smoothtexture.hlslh +smoothtexture_vshader.entry = VS_SmoothTexture +smoothtexture_vshader.type = vs_5_0 +smoothtexture_pshader.input = smoothtexture_VSPS +smoothtexture_pshader.header = ps_smoothtexture.hlslh +smoothtexture_pshader.entry = PS_SmoothTexture +smoothtexture_pshader.type = ps_5_0 + +mipmapgen_CS = $$PWD/mipmapgen.hlsl +mipmapgen_cshader.input = mipmapgen_CS +mipmapgen_cshader.header = cs_mipmapgen.hlslh +mipmapgen_cshader.entry = CS_Generate4MipMaps +mipmapgen_cshader.type = cs_5_0 + +textmask_VSPS = $$PWD/textmask.hlsl +textmask_vshader.input = textmask_VSPS +textmask_vshader.header = vs_textmask.hlslh +textmask_vshader.entry = VS_TextMask +textmask_vshader.type = vs_5_0 +textmask_pshader24.input = textmask_VSPS +textmask_pshader24.header = ps_textmask24.hlslh +textmask_pshader24.entry = PS_TextMask24 +textmask_pshader24.type = ps_5_0 +textmask_pshader32.input = textmask_VSPS +textmask_pshader32.header = ps_textmask32.hlslh +textmask_pshader32.entry = PS_TextMask32 +textmask_pshader32.type = ps_5_0 +textmask_pshader8.input = textmask_VSPS +textmask_pshader8.header = ps_textmask8.hlslh +textmask_pshader8.entry = PS_TextMask8 +textmask_pshader8.type = ps_5_0 +styledtext_vshader.input = textmask_VSPS +styledtext_vshader.header = vs_styledtext.hlslh +styledtext_vshader.entry = VS_StyledText +styledtext_vshader.type = vs_5_0 +styledtext_pshader.input = textmask_VSPS +styledtext_pshader.header = ps_styledtext.hlslh +styledtext_pshader.entry = PS_StyledText +styledtext_pshader.type = ps_5_0 +outlinedtext_vshader.input = textmask_VSPS +outlinedtext_vshader.header = vs_outlinedtext.hlslh +outlinedtext_vshader.entry = VS_OutlinedText +outlinedtext_vshader.type = vs_5_0 +outlinedtext_pshader.input = textmask_VSPS +outlinedtext_pshader.header = ps_outlinedtext.hlslh +outlinedtext_pshader.entry = PS_OutlinedText +outlinedtext_pshader.type = ps_5_0 + +HLSL_SHADERS = \ + vertexcolor_vshader vertexcolor_pshader \ + stencilclip_vshader stencilclip_pshader \ + smoothcolor_vshader smoothcolor_pshader \ + texture_vshader texture_pshader \ + smoothtexture_vshader smoothtexture_pshader \ + mipmapgen_cshader \ + textmask_vshader textmask_pshader24 textmask_pshader32 textmask_pshader8 \ + styledtext_vshader styledtext_pshader outlinedtext_vshader outlinedtext_pshader + +load(hlsl_bytecode_header) diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl new file mode 100644 index 0000000000..4f69eea60f --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/shaders/smoothcolor.hlsl @@ -0,0 +1,64 @@ +struct VSInput +{ + float4 position : POSITION; + float4 color : COLOR; + float2 offset : TEXCOORD0; +}; + +cbuffer ConstantBuffer : register(b0) +{ + float4x4 mvp; + float opacity; + float2 pixelSize; +}; + +struct PSInput +{ + float4 position : SV_POSITION; + float4 color : COLOR; +}; + +PSInput VS_SmoothColor(VSInput input) +{ + PSInput result; + + float4 pos = mul(mvp, input.position); + + if (input.offset.x != 0.0) { + // In HLSL matrix packing is column-major by default (which is good) but the math is row-major (unlike GLSL). + float4 delta = float4(mvp._11, mvp._21, mvp._31, mvp._41) * input.offset.x; + float2 dir = delta.xy * pos.w - pos.xy * delta.w; + float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize); + dir -= ndir * delta.w * pos.w; + float numerator = dot(dir, ndir * pos.w * pos.w); + float scale = 0.0; + if (numerator < 0.0) + scale = 1.0; + else + scale = min(1.0, numerator / dot(dir, dir)); + pos += scale * delta; + } + + if (input.offset.y != 0.0) { + float4 delta = float4(mvp._12, mvp._22, mvp._32, mvp._42) * input.offset.y; + float2 dir = delta.xy * pos.w - pos.xy * delta.w; + float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize); + dir -= ndir * delta.w * pos.w; + float numerator = dot(dir, ndir * pos.w * pos.w); + float scale = 0.0; + if (numerator < 0.0) + scale = 1.0; + else + scale = min(1.0, numerator / dot(dir, dir)); + pos += scale * delta; + } + + result.position = pos; + result.color = input.color * opacity; + return result; +} + +float4 PS_SmoothColor(PSInput input) : SV_TARGET +{ + return input.color; +} diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/smoothtexture.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/smoothtexture.hlsl new file mode 100644 index 0000000000..05b1c6e9d4 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/shaders/smoothtexture.hlsl @@ -0,0 +1,77 @@ +struct VSInput +{ + float4 position : POSITION; + float2 coord : TEXCOORD0; + float2 offset : TEXCOORD1; + float2 coordOffset : TEXCOORD2; +}; + +cbuffer ConstantBuffer : register(b0) +{ + float4x4 mvp; + float opacity; + float2 pixelSize; +}; + +struct PSInput +{ + float4 position : SV_POSITION; + float2 coord : TEXCOORD0; + float vertexOpacity : TEXCOORD3; +}; + +Texture2D tex : register(t0); +SamplerState samp : register(s0); + +PSInput VS_SmoothTexture(VSInput input) +{ + PSInput result; + + float4 pos = mul(mvp, input.position); + float2 coord = input.coord; + + if (input.offset.x != 0.0) { + // In HLSL matrix packing is column-major by default (which is good) but the math is row-major (unlike GLSL). + float4 delta = float4(mvp._11, mvp._21, mvp._31, mvp._41) * input.offset.x; + float2 dir = delta.xy * pos.w - pos.xy * delta.w; + float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize); + dir -= ndir * delta.w * pos.w; + float numerator = dot(dir, ndir * pos.w * pos.w); + float scale = 0.0; + if (numerator < 0.0) + scale = 1.0; + else + scale = min(1.0, numerator / dot(dir, dir)); + pos += scale * delta; + coord.x += scale * input.coordOffset.x; + } + + if (input.offset.y != 0.0) { + float4 delta = float4(mvp._12, mvp._22, mvp._32, mvp._42) * input.offset.y; + float2 dir = delta.xy * pos.w - pos.xy * delta.w; + float2 ndir = 0.5 * pixelSize * normalize(dir / pixelSize); + dir -= ndir * delta.w * pos.w; + float numerator = dot(dir, ndir * pos.w * pos.w); + float scale = 0.0; + if (numerator < 0.0) + scale = 1.0; + else + scale = min(1.0, numerator / dot(dir, dir)); + pos += scale * delta; + coord.y += scale * input.coordOffset.y; + } + + if ((input.offset.x != 0.0 || input.offset.y != 0.0) && (input.coordOffset.x == 0.0 && input.coordOffset.y == 0.0)) + result.vertexOpacity = 0.0; + else + result.vertexOpacity = opacity; + + result.position = pos; + result.coord = coord; + return result; +} + +float4 PS_SmoothTexture(PSInput input) : SV_TARGET +{ + return tex.Sample(samp, input.coord) * input.vertexOpacity; +} diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/stencilclip.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/stencilclip.hlsl new file mode 100644 index 0000000000..9aff84d261 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/shaders/stencilclip.hlsl @@ -0,0 +1,26 @@ +struct VSInput +{ + float4 position : POSITION; +}; + +cbuffer ConstantBuffer : register(b0) +{ + float4x4 mvp; +}; + +struct PSInput +{ + float4 position : SV_POSITION; +}; + +PSInput VS_StencilClip(VSInput input) +{ + PSInput result; + result.position = mul(mvp, input.position); + return result; +} + +float4 PS_StencilClip(PSInput input) : SV_TARGET +{ + return float4(0.81, 0.83, 0.12, 1.0); // Trolltech green ftw! +} diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/textmask.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/textmask.hlsl new file mode 100644 index 0000000000..f9d92e8ee9 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/shaders/textmask.hlsl @@ -0,0 +1,104 @@ +struct VSInput +{ + float4 position : POSITION; + float2 coord : TEXCOORD0; +}; + +cbuffer ConstantBuffer : register(b0) +{ + float4x4 mvp; + float2 textureScale; + float dpr; + float color; // for TextMask24 and 32 + float4 colorVec; // for TextMask8 and Styled and Outlined + float2 shift; // for Styled + float4 styleColor; // for Styled and Outlined +}; + +struct PSInput +{ + float4 position : SV_POSITION; + float2 coord : TEXCOORD0; +}; + +Texture2D tex : register(t0); +SamplerState samp : register(s0); + +PSInput VS_TextMask(VSInput input) +{ + PSInput result; + result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr); + result.coord = input.coord * textureScale; + return result; +} + +float4 PS_TextMask24(PSInput input) : SV_TARGET +{ + float4 glyph = tex.Sample(samp, input.coord); + return float4(glyph.rgb * color, glyph.a); +} + +float4 PS_TextMask32(PSInput input) : SV_TARGET +{ + return tex.Sample(samp, input.coord) * color; +} + +float4 PS_TextMask8(PSInput input) : SV_TARGET +{ + return colorVec * tex.Sample(samp, input.coord).r; +} + +struct StyledPSInput +{ + float4 position : SV_POSITION; + float2 coord : TEXCOORD0; + float2 shiftedCoord : TEXCOORD1; +}; + +StyledPSInput VS_StyledText(VSInput input) +{ + StyledPSInput result; + result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr); + result.coord = input.coord * textureScale; + result.shiftedCoord = (input.coord - shift) * textureScale; + return result; +} + +float4 PS_StyledText(StyledPSInput input) : SV_TARGET +{ + float glyph = tex.Sample(samp, input.coord).r; + float style = clamp(tex.Sample(samp, input.shiftedCoord).r - glyph, 0.0, 1.0); + return style * styleColor + glyph * colorVec; +} + +struct OutlinedPSInput +{ + float4 position : SV_POSITION; + float2 coord : TEXCOORD0; + float2 coordUp : TEXCOORD1; + float2 coordDown : TEXCOORD2; + float2 coordLeft : TEXCOORD3; + float2 coordRight : TEXCOORD4; +}; + +OutlinedPSInput VS_OutlinedText(VSInput input) +{ + OutlinedPSInput result; + result.position = mul(mvp, floor(input.position * dpr + 0.5) / dpr); + result.coord = input.coord * textureScale; + result.coordUp = (input.coord - float2(0.0, -1.0)) * textureScale; + result.coordDown = (input.coord - float2(0.0, 1.0)) * textureScale; + result.coordLeft = (input.coord - float2(-1.0, 0.0)) * textureScale; + result.coordRight = (input.coord - float2(1.0, 0.0)) * textureScale; + return result; +} + +float4 PS_OutlinedText(OutlinedPSInput input) : SV_TARGET +{ + float glyph = tex.Sample(samp, input.coord).r; + float outline = clamp(clamp(tex.Sample(samp, input.coordUp).r + + tex.Sample(samp, input.coordDown).r + + tex.Sample(samp, input.coordLeft).r + + tex.Sample(samp, input.coordRight).r, 0.0, 1.0) - glyph, 0.0, 1.0); + return outline * styleColor + glyph * colorVec; +} diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/texture.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/texture.hlsl new file mode 100644 index 0000000000..1ae6579e8d --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/shaders/texture.hlsl @@ -0,0 +1,33 @@ +struct VSInput +{ + float4 position : POSITION; + float2 coord : TEXCOORD0; +}; + +cbuffer ConstantBuffer : register(b0) +{ + float4x4 mvp; + float opacity; +}; + +struct PSInput +{ + float4 position : SV_POSITION; + float2 coord : TEXCOORD0; +}; + +Texture2D tex : register(t0); +SamplerState samp : register(s0); + +PSInput VS_Texture(VSInput input) +{ + PSInput result; + result.position = mul(mvp, input.position); + result.coord = input.coord; + return result; +} + +float4 PS_Texture(PSInput input) : SV_TARGET +{ + return tex.Sample(samp, input.coord) * opacity; +} diff --git a/src/quick/scenegraph/adaptations/d3d12/shaders/vertexcolor.hlsl b/src/quick/scenegraph/adaptations/d3d12/shaders/vertexcolor.hlsl new file mode 100644 index 0000000000..a0569bb5c1 --- /dev/null +++ b/src/quick/scenegraph/adaptations/d3d12/shaders/vertexcolor.hlsl @@ -0,0 +1,32 @@ +struct VSInput +{ + float4 position : POSITION; + float4 color : COLOR; +}; + +cbuffer ConstantBuffer : register(b0) +{ + float4x4 mvp; + float opacity; +}; + +struct PSInput +{ + float4 position : SV_POSITION; + float4 color : COLOR; +}; + +PSInput VS_VertexColor(VSInput input) +{ + PSInput result; + + result.position = mul(mvp, input.position); + result.color = input.color * opacity; + + return result; +} + +float4 PS_VertexColor(PSInput input) : SV_TARGET +{ + return input.color; +} diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp new file mode 100644 index 0000000000..4ceaa08197 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp @@ -0,0 +1,321 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgabstractsoftwarerenderer_p.h" + +#include "qsgsoftwarerenderablenodeupdater_p.h" +#include "qsgsoftwarerenderlistbuilder_p.h" +#include "qsgsoftwarecontext_p.h" +#include "qsgsoftwarerenderablenode_p.h" + +#include <QtCore/QLoggingCategory> +#include <QtGui/QWindow> +#include <QtQuick/QSGSimpleRectNode> + +Q_LOGGING_CATEGORY(lc2DRender, "qt.scenegraph.softwarecontext.abstractrenderer") + +QT_BEGIN_NAMESPACE + +QSGAbstractSoftwareRenderer::QSGAbstractSoftwareRenderer(QSGRenderContext *context) + : QSGRenderer(context) + , m_background(new QSGSimpleRectNode) + , m_nodeUpdater(new QSGSoftwareRenderableNodeUpdater(this)) +{ + // Setup special background node + auto backgroundRenderable = new QSGSoftwareRenderableNode(QSGSoftwareRenderableNode::SimpleRect, m_background); + addNodeMapping(m_background, backgroundRenderable); +} + +QSGAbstractSoftwareRenderer::~QSGAbstractSoftwareRenderer() +{ + // Cleanup RenderableNodes + delete m_background; + + for (QSGSoftwareRenderableNode *node : m_nodes.values()) { + delete node; + } + + delete m_nodeUpdater; +} + +QSGSoftwareRenderableNode *QSGAbstractSoftwareRenderer::renderableNode(QSGNode *node) const +{ + return m_nodes.value(node, nullptr); +} + +void QSGAbstractSoftwareRenderer::addNodeMapping(QSGNode *node, QSGSoftwareRenderableNode *renderableNode) +{ + m_nodes.insert(node, renderableNode); +} + +void QSGAbstractSoftwareRenderer::appendRenderableNode(QSGSoftwareRenderableNode *node) +{ + m_renderableNodes.append(node); +} + +void QSGAbstractSoftwareRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) +{ + if (state & QSGNode::DirtyGeometry) { + nodeGeometryUpdated(node); + } + if (state & QSGNode::DirtyMaterial) { + nodeMaterialUpdated(node); + } + if (state & QSGNode::DirtyMatrix) { + nodeMatrixUpdated(node); + } + if (state & QSGNode::DirtyNodeAdded) { + nodeAdded(node); + } + if (state & QSGNode::DirtyNodeRemoved) { + nodeRemoved(node); + } + if (state & QSGNode::DirtyOpacity) { + nodeOpacityUpdated(node); + } + if (state & QSGNode::DirtySubtreeBlocked) { + m_nodeUpdater->updateNodes(node); + } + if (state & QSGNode::DirtyForceUpdate) { + m_nodeUpdater->updateNodes(node); + } + QSGRenderer::nodeChanged(node, state); +} + +QRegion QSGAbstractSoftwareRenderer::renderNodes(QPainter *painter) +{ + QRegion dirtyRegion; + // If there are no nodes, do nothing + if (m_renderableNodes.isEmpty()) + return dirtyRegion; + + auto iterator = m_renderableNodes.begin(); + // First node is the background and needs to painted without blending + auto backgroundNode = *iterator; + dirtyRegion += backgroundNode->renderNode(painter, /*force opaque painting*/ true); + iterator++; + + for (; iterator != m_renderableNodes.end(); ++iterator) { + auto node = *iterator; + dirtyRegion += node->renderNode(painter); + } + + return dirtyRegion; +} + +void QSGAbstractSoftwareRenderer::buildRenderList() +{ + // Clear the previous renderlist + m_renderableNodes.clear(); + // Add the background renderable (always first) + m_renderableNodes.append(renderableNode(m_background)); + // Build the renderlist + QSGSoftwareRenderListBuilder(this).visitChildren(rootNode()); +} + +void QSGAbstractSoftwareRenderer::optimizeRenderList() +{ + // Iterate through the renderlist from front to back + // Objective is to update the dirty status and rects. + for (auto i = m_renderableNodes.rbegin(); i != m_renderableNodes.rend(); ++i) { + auto node = *i; + if (!m_dirtyRegion.isEmpty()) { + // See if the current dirty regions apply to the current node + node->addDirtyRegion(m_dirtyRegion, true); + } + + if (!m_obscuredRegion.isEmpty()) { + // Don't try to paint things that are covered by opaque objects + node->subtractDirtyRegion(m_obscuredRegion); + } + + // Keep up with obscured regions + if (node->isOpaque()) { + m_obscuredRegion += QRegion(node->boundingRect()); + } + + if (node->isDirty()) { + // Don't paint things outside of the rendering area + if (!m_background->rect().toRect().contains(node->boundingRect(), /*proper*/ true)) { + // Some part(s) of node is(are) outside of the rendering area + QRegion renderArea(m_background->rect().toRect()); + QRegion outsideRegions = node->dirtyRegion().subtracted(renderArea); + if (!outsideRegions.isEmpty()) + node->subtractDirtyRegion(outsideRegions); + } + + // Get the dirty region's to pass to the next nodes + if (node->isOpaque()) { + // if isOpaque, subtract node's dirty rect from m_dirtyRegion + m_dirtyRegion -= node->dirtyRegion(); + } else { + // if isAlpha, add node's dirty rect to m_dirtyRegion + m_dirtyRegion += node->dirtyRegion(); + } + // if previousDirtyRegion has content outside of boundingRect add to m_dirtyRegion + QRegion prevDirty = node->previousDirtyRegion(); + if (!prevDirty.isNull()) + m_dirtyRegion += prevDirty; + } + } + + // Empty dirtyRegion (for second pass) + m_dirtyRegion = QRegion(); + m_obscuredRegion = QRegion(); + + // Iterate through the renderlist from back to front + // Objective is to make sure all non-opaque items are painted when an item under them is dirty + for (auto j = m_renderableNodes.begin(); j != m_renderableNodes.end(); ++j) { + auto node = *j; + + if (!node->isOpaque() && !m_dirtyRegion.isEmpty()) { + // Only blended nodes need to be updated + node->addDirtyRegion(m_dirtyRegion, true); + } + + m_dirtyRegion += node->dirtyRegion(); + } + + // Empty dirtyRegion + m_dirtyRegion = QRegion(); + m_obscuredRegion = QRegion(); +} + +void QSGAbstractSoftwareRenderer::setBackgroundColor(const QColor &color) +{ + if (m_background->color() == color) + return; + m_background->setColor(color); + renderableNode(m_background)->markMaterialDirty(); +} + +void QSGAbstractSoftwareRenderer::setBackgroundSize(const QSize &size) +{ + if (m_background->rect().size().toSize() == size) + return; + m_background->setRect(0.0f, 0.0f, size.width(), size.height()); + renderableNode(m_background)->markGeometryDirty(); + // Invalidate the whole scene when the background is resized + m_dirtyRegion = QRegion(m_background->rect().toRect()); +} + +QColor QSGAbstractSoftwareRenderer::backgroundColor() +{ + return m_background->color(); +} + +QSize QSGAbstractSoftwareRenderer::backgroundSize() +{ + return m_background->rect().size().toSize(); +} + +void QSGAbstractSoftwareRenderer::nodeAdded(QSGNode *node) +{ + qCDebug(lc2DRender) << "nodeAdded" << (void*)node; + + m_nodeUpdater->updateNodes(node); +} + +void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node) +{ + qCDebug(lc2DRender) << "nodeRemoved" << (void*)node; + + auto renderable = renderableNode(node); + // remove mapping + if (renderable != nullptr) { + // Need to mark this region dirty in the other nodes + QRegion dirtyRegion = renderable->previousDirtyRegion(); + if (dirtyRegion.isEmpty()) + dirtyRegion = renderable->boundingRect(); + m_dirtyRegion += dirtyRegion; + m_nodes.remove(node); + delete renderable; + } + + // Remove all children nodes as well + for (QSGNode *child = node->firstChild(); child; child = child->nextSibling()) { + nodeRemoved(child); + } + + m_nodeUpdater->updateNodes(node, true); +} + +void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node) +{ + qCDebug(lc2DRender) << "nodeGeometryUpdated"; + + // Mark node as dirty + auto renderable = renderableNode(node); + if (renderable != nullptr) { + renderable->markGeometryDirty(); + } else { + m_nodeUpdater->updateNodes(node); + } +} + +void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node) +{ + qCDebug(lc2DRender) << "nodeMaterialUpdated"; + + // Mark node as dirty + auto renderable = renderableNode(node); + if (renderable != nullptr) { + renderable->markMaterialDirty(); + } else { + m_nodeUpdater->updateNodes(node); + } +} + +void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node) +{ + qCDebug(lc2DRender) << "nodeMaterialUpdated"; + + // Update children nodes + m_nodeUpdater->updateNodes(node); +} + +void QSGAbstractSoftwareRenderer::nodeOpacityUpdated(QSGNode *node) +{ + qCDebug(lc2DRender) << "nodeOpacityUpdated"; + + // Update children nodes + m_nodeUpdater->updateNodes(node); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h new file mode 100644 index 0000000000..87e1e594c6 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGABSTRACTSOFTWARERENDERER_H +#define QSGABSTRACTSOFTWARERENDERER_H + +#include <private/qsgrenderer_p.h> + +#include <QtCore/QHash> +#include <QtCore/QLinkedList> + +QT_BEGIN_NAMESPACE + +class QSGSimpleRectNode; + +class QSGSoftwareRenderableNode; +class QSGSoftwareRenderableNodeUpdater; + +class QSGAbstractSoftwareRenderer : public QSGRenderer +{ +public: + QSGAbstractSoftwareRenderer(QSGRenderContext *context); + virtual ~QSGAbstractSoftwareRenderer(); + + QSGSoftwareRenderableNode *renderableNode(QSGNode *node) const; + void addNodeMapping(QSGNode *node, QSGSoftwareRenderableNode *renderableNode); + void appendRenderableNode(QSGSoftwareRenderableNode *node); + + void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override; + +protected: + QRegion renderNodes(QPainter *painter); + void buildRenderList(); + void optimizeRenderList(); + + void setBackgroundColor(const QColor &color); + void setBackgroundSize(const QSize &size); + QColor backgroundColor(); + QSize backgroundSize(); + +private: + void nodeAdded(QSGNode *node); + void nodeRemoved(QSGNode *node); + void nodeGeometryUpdated(QSGNode *node); + void nodeMaterialUpdated(QSGNode *node); + void nodeMatrixUpdated(QSGNode *node); + void nodeOpacityUpdated(QSGNode *node); + + QHash<QSGNode*, QSGSoftwareRenderableNode*> m_nodes; + QLinkedList<QSGSoftwareRenderableNode*> m_renderableNodes; + + QSGSimpleRectNode *m_background; + + QRegion m_dirtyRegion; + QRegion m_obscuredRegion; + + QSGSoftwareRenderableNodeUpdater *m_nodeUpdater; +}; + +QT_END_NAMESPACE + +#endif // QSGABSTRACTSOFTWARERENDERER_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp new file mode 100644 index 0000000000..55d226bf93 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwareadaptation_p.h" +#include "qsgsoftwarecontext_p.h" +#include "qsgsoftwarerenderloop_p.h" + +#include <private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> + +QT_BEGIN_NAMESPACE + +QSGSoftwareAdaptation::QSGSoftwareAdaptation(QObject *parent) + : QSGContextPlugin(parent) +{ +} + +QStringList QSGSoftwareAdaptation::keys() const +{ + return QStringList() << QLatin1String("software"); +} + +QSGContext *QSGSoftwareAdaptation::create(const QString &) const +{ + if (!instance) + instance = new QSGSoftwareContext(); + return instance; +} + +QSGRenderLoop *QSGSoftwareAdaptation::createWindowManager() +{ + return new QSGSoftwareRenderLoop(); +} + +QSGSoftwareContext *QSGSoftwareAdaptation::instance = 0; + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h new file mode 100644 index 0000000000..3bdfd0e90d --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLUGINMAIN_H +#define PLUGINMAIN_H + +#include <private/qsgcontextplugin_p.h> + +QT_BEGIN_NAMESPACE + +class QSGContext; +class QSGRenderLoop; +class QSGSoftwareContext; + +class QSGSoftwareAdaptation : public QSGContextPlugin +{ +public: + QSGSoftwareAdaptation(QObject *parent = 0); + + QStringList keys() const override; + QSGContext *create(const QString &key) const override; + QSGRenderLoop *createWindowManager() override; +private: + static QSGSoftwareContext *instance; +}; + +QT_END_NAMESPACE + +#endif // PLUGINMAIN_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp new file mode 100644 index 0000000000..04fc6da84e --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarecontext_p.h" + +#include "qsgsoftwarerectanglenode_p.h" +#include "qsgsoftwareimagenode_p.h" +#include "qsgsoftwarepainternode_p.h" +#include "qsgsoftwarepixmaptexture_p.h" +#include "qsgsoftwareglyphnode_p.h" +#include "qsgsoftwareninepatchnode_p.h" +#include "qsgsoftwarelayer_p.h" +#include "qsgsoftwarerenderer_p.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/QElapsedTimer> + +#include <QtGui/QWindow> + +#include <QtQuick/QSGFlatColorMaterial> +#include <QtQuick/QSGVertexColorMaterial> +#include <QtQuick/QSGOpaqueTextureMaterial> +#include <QtQuick/QSGTextureMaterial> + +#ifndef QSG_NO_RENDERER_TIMING +static bool qsg_render_timing = !qgetenv("QSG_RENDER_TIMING").isEmpty(); +#endif + +// Used for very high-level info about the renderering and gl context +// Includes GL_VERSION, type of render loop, atlas size, etc. +Q_LOGGING_CATEGORY(QSG_RASTER_LOG_INFO, "qt.scenegraph.info") + +// Used to debug the renderloop logic. Primarily useful for platform integrators +// and when investigating the render loop logic. +Q_LOGGING_CATEGORY(QSG_RASTER_LOG_RENDERLOOP, "qt.scenegraph.renderloop") + +// GLSL shader compilation +Q_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_COMPILATION, "qt.scenegraph.time.compilation") + +// polish, animations, sync, render and swap in the render loop +Q_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_RENDERLOOP, "qt.scenegraph.time.renderloop") + +// Texture uploads and swizzling +Q_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_TEXTURE, "qt.scenegraph.time.texture") + +// Glyph preparation (only for distance fields atm) +Q_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_GLYPH, "qt.scenegraph.time.glyph") + +// Timing inside the renderer base class +Q_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_RENDERER, "qt.scenegraph.time.renderer") + +QT_BEGIN_NAMESPACE + +QSGSoftwareRenderContext::QSGSoftwareRenderContext(QSGContext *ctx) + : QSGRenderContext(ctx) + , currentWindow(0) + , m_initialized(false) +{ +} +QSGSoftwareContext::QSGSoftwareContext(QObject *parent) + : QSGContext(parent) +{ +} + +QSGRectangleNode *QSGSoftwareContext::createRectangleNode() +{ + return new QSGSoftwareRectangleNode(); +} + +QSGImageNode *QSGSoftwareContext::createImageNode() +{ + return new QSGSoftwareImageNode(); +} + +QSGPainterNode *QSGSoftwareContext::createPainterNode(QQuickPaintedItem *item) +{ + return new QSGSoftwarePainterNode(item); +} + +QSGGlyphNode *QSGSoftwareContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) +{ + Q_UNUSED(rc); + Q_UNUSED(preferNativeGlyphNode); + return new QSGSoftwareGlyphNode(); +} + +QSGNinePatchNode *QSGSoftwareContext::createNinePatchNode() +{ + return new QSGSoftwareNinePatchNode(); +} + +QSGLayer *QSGSoftwareContext::createLayer(QSGRenderContext *renderContext) +{ + return new QSGSoftwareLayer(renderContext); +} + +QSurfaceFormat QSGSoftwareContext::defaultSurfaceFormat() const +{ + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); + format.setRenderableType(QSurfaceFormat::DefaultRenderableType); + format.setMajorVersion(0); + format.setMinorVersion(0); + return format; +} + +void QSGSoftwareRenderContext::initializeIfNeeded() +{ + if (m_initialized) + return; + m_initialized = true; + emit initialized(); +} + +void QSGSoftwareRenderContext::invalidate() +{ + QSGRenderContext::invalidate(); +} + +QSGTexture *QSGSoftwareRenderContext::createTexture(const QImage &image, uint flags) const +{ + Q_UNUSED(flags) + return new QSGSoftwarePixmapTexture(image); +} + +QSGRenderer *QSGSoftwareRenderContext::createRenderer() +{ + return new QSGSoftwareRenderer(this); +} + + +void QSGSoftwareRenderContext::renderNextFrame(QSGRenderer *renderer, uint fbo) +{ + renderer->renderScene(fbo); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h new file mode 100644 index 0000000000..a150676ea1 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARECONTEXT_H +#define QSGSOFTWARECONTEXT_H + +#include <private/qsgcontext_p.h> +#include <private/qsgadaptationlayer_p.h> + +Q_DECLARE_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_RENDERLOOP) +Q_DECLARE_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_COMPILATION) +Q_DECLARE_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_TEXTURE) +Q_DECLARE_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_GLYPH) +Q_DECLARE_LOGGING_CATEGORY(QSG_RASTER_LOG_TIME_RENDERER) +Q_DECLARE_LOGGING_CATEGORY(QSG_RASTER_LOG_INFO) +Q_DECLARE_LOGGING_CATEGORY(QSG_RASTER_LOG_RENDERLOOP) + +QT_BEGIN_NAMESPACE + +class QSGSoftwareRenderContext : public QSGRenderContext +{ + Q_OBJECT +public: + QSGSoftwareRenderContext(QSGContext *ctx); + void initializeIfNeeded(); + void invalidate() override; + void renderNextFrame(QSGRenderer *renderer, uint fbo) override; + QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const override; + QSGRenderer *createRenderer() override; + + QWindow *currentWindow; + bool m_initialized; +}; + +class QSGSoftwareContext : public QSGContext +{ + Q_OBJECT +public: + explicit QSGSoftwareContext(QObject *parent = nullptr); + + QSGRenderContext *createRenderContext() override { return new QSGSoftwareRenderContext(this); } + QSGRectangleNode *createRectangleNode() override; + QSGImageNode *createImageNode() override; + QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override; + QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override; + QSGNinePatchNode *createNinePatchNode() override; + QSGLayer *createLayer(QSGRenderContext *renderContext) override; + QSurfaceFormat defaultSurfaceFormat() const override; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWARECONTEXT_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp new file mode 100644 index 0000000000..d22830a831 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwareglyphnode_p.h" + +QT_BEGIN_NAMESPACE + +QSGSoftwareGlyphNode::QSGSoftwareGlyphNode() + : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) + , m_style(QQuickText::Normal) +{ + setMaterial((QSGMaterial*)1); + setGeometry(&m_geometry); +} + + +void QSGSoftwareGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs) +{ + m_position = position; + m_glyphRun = glyphs; + m_bounding_rect = glyphs.boundingRect().translated(m_position - QPointF(0.0, glyphs.rawFont().ascent())); +} + +void QSGSoftwareGlyphNode::setColor(const QColor &color) +{ + m_color = color; +} + +void QSGSoftwareGlyphNode::setStyle(QQuickText::TextStyle style) +{ + m_style = style; +} + +void QSGSoftwareGlyphNode::setStyleColor(const QColor &color) +{ + m_styleColor = color; +} + +QPointF QSGSoftwareGlyphNode::baseLine() const +{ + return QPointF(); +} + +void QSGSoftwareGlyphNode::setPreferredAntialiasingMode(QSGGlyphNode::AntialiasingMode) +{ +} + +void QSGSoftwareGlyphNode::update() +{ +} + +void QSGSoftwareGlyphNode::paint(QPainter *painter) +{ + painter->setBrush(QBrush()); + QPointF pos = m_position - QPointF(0, m_glyphRun.rawFont().ascent()); + + switch (m_style) { + case QQuickText::Normal: break; + case QQuickText::Outline: + painter->setPen(m_styleColor); + painter->drawGlyphRun(pos + QPointF(0, 1), m_glyphRun); + painter->drawGlyphRun(pos + QPointF(0, -1), m_glyphRun); + painter->drawGlyphRun(pos + QPointF(1, 0), m_glyphRun); + painter->drawGlyphRun(pos + QPointF(-1, 0), m_glyphRun); + break; + case QQuickText::Raised: + painter->setPen(m_styleColor); + painter->drawGlyphRun(pos + QPointF(0, 1), m_glyphRun); + break; + case QQuickText::Sunken: + painter->setPen(m_styleColor); + painter->drawGlyphRun(pos + QPointF(0, -1), m_glyphRun); + break; + } + + painter->setPen(m_color); + painter->drawGlyphRun(pos, m_glyphRun); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode_p.h new file mode 100644 index 0000000000..e7efc6da9d --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWAREGLYPHNODE_H +#define QSGSOFTWAREGLYPHNODE_H + +#include <private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +class QSGSoftwareGlyphNode : public QSGGlyphNode +{ +public: + QSGSoftwareGlyphNode(); + + void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) override; + void setColor(const QColor &color) override; + void setStyle(QQuickText::TextStyle style) override; + void setStyleColor(const QColor &color) override; + QPointF baseLine() const override; + void setPreferredAntialiasingMode(AntialiasingMode) override; + void update() override; + + void paint(QPainter *painter); + +private: + QPointF m_position; + QGlyphRun m_glyphRun; + QColor m_color; + QSGGeometry m_geometry; + QQuickText::TextStyle m_style; + QColor m_styleColor; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWAREGLYPHNODE_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareimagenode.cpp new file mode 100644 index 0000000000..7dadc1d3d4 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareimagenode.cpp @@ -0,0 +1,503 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwareimagenode_p.h" + +#include "qsgsoftwarepixmaptexture_p.h" +#include "qsgsoftwarelayer_p.h" +#include <QPainter> +#include <qmath.h> + +QT_BEGIN_NAMESPACE + +namespace QSGSoftwareHelpers { +// Helper from widgets/styles/qdrawutil.cpp + +static inline QMargins normalizedMargins(const QMargins &m) +{ + return QMargins(qMax(m.left(), 0), qMax(m.top(), 0), qMax(m.right(), 0), qMax(m.bottom(), 0)); +} + +void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMarginsIn, + const QPixmap &pixmap, const QRect &sourceRect, const QMargins &sourceMarginsIn, + const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints) +{ + QPainter::PixmapFragment d; + d.opacity = 1.0; + d.rotation = 0.0; + + QPixmapFragmentsArray opaqueData; + QPixmapFragmentsArray translucentData; + + QMargins sourceMargins = normalizedMargins(sourceMarginsIn); + QMargins targetMargins = normalizedMargins(targetMarginsIn); + + // source center + const int sourceCenterTop = sourceRect.top() + sourceMargins.top(); + const int sourceCenterLeft = sourceRect.left() + sourceMargins.left(); + const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1; + const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1; + const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft; + const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop; + // target center + const int targetCenterTop = targetRect.top() + targetMargins.top(); + const int targetCenterLeft = targetRect.left() + targetMargins.left(); + const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1; + const int targetCenterRight = targetRect.right() - targetMargins.right() + 1; + const int targetCenterWidth = targetCenterRight - targetCenterLeft; + const int targetCenterHeight = targetCenterBottom - targetCenterTop; + + QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles + QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles + + int columns = 3; + int rows = 3; + if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0) + columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth))); + if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0) + rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight))); + + xTarget.resize(columns + 1); + yTarget.resize(rows + 1); + + bool oldAA = painter->testRenderHint(QPainter::Antialiasing); + if (painter->paintEngine()->type() != QPaintEngine::OpenGL + && painter->paintEngine()->type() != QPaintEngine::OpenGL2 + && oldAA && painter->combinedTransform().type() != QTransform::TxNone) { + painter->setRenderHint(QPainter::Antialiasing, false); + } + + xTarget[0] = targetRect.left(); + xTarget[1] = targetCenterLeft; + xTarget[columns - 1] = targetCenterRight; + xTarget[columns] = targetRect.left() + targetRect.width(); + + yTarget[0] = targetRect.top(); + yTarget[1] = targetCenterTop; + yTarget[rows - 1] = targetCenterBottom; + yTarget[rows] = targetRect.top() + targetRect.height(); + + qreal dx = targetCenterWidth; + qreal dy = targetCenterHeight; + + switch (rules.horizontal) { + case Qt::StretchTile: + dx = targetCenterWidth; + break; + case Qt::RepeatTile: + dx = sourceCenterWidth; + break; + case Qt::RoundTile: + dx = targetCenterWidth / qreal(columns - 2); + break; + } + + for (int i = 2; i < columns - 1; ++i) + xTarget[i] = xTarget[i - 1] + dx; + + switch (rules.vertical) { + case Qt::StretchTile: + dy = targetCenterHeight; + break; + case Qt::RepeatTile: + dy = sourceCenterHeight; + break; + case Qt::RoundTile: + dy = targetCenterHeight / qreal(rows - 2); + break; + } + + for (int i = 2; i < rows - 1; ++i) + yTarget[i] = yTarget[i - 1] + dy; + + // corners + if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left + d.x = (0.5 * (xTarget[1] + xTarget[0])); + d.y = (0.5 * (yTarget[1] + yTarget[0])); + d.sourceLeft = sourceRect.left(); + d.sourceTop = sourceRect.top(); + d.width = sourceMargins.left(); + d.height = sourceMargins.top(); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; + if (hints & QDrawBorderPixmap::OpaqueTopLeft) + opaqueData.append(d); + else + translucentData.append(d); + } + if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right + d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.y = (0.5 * (yTarget[1] + yTarget[0])); + d.sourceLeft = sourceCenterRight; + d.sourceTop = sourceRect.top(); + d.width = sourceMargins.right(); + d.height = sourceMargins.top(); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; + if (hints & QDrawBorderPixmap::OpaqueTopRight) + opaqueData.append(d); + else + translucentData.append(d); + } + if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left + d.x = (0.5 * (xTarget[1] + xTarget[0])); + d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.sourceLeft = sourceRect.left(); + d.sourceTop = sourceCenterBottom; + d.width = sourceMargins.left(); + d.height = sourceMargins.bottom(); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; + if (hints & QDrawBorderPixmap::OpaqueBottomLeft) + opaqueData.append(d); + else + translucentData.append(d); + } + if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right + d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.sourceLeft = sourceCenterRight; + d.sourceTop = sourceCenterBottom; + d.width = sourceMargins.right(); + d.height = sourceMargins.bottom(); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; + if (hints & QDrawBorderPixmap::OpaqueBottomRight) + opaqueData.append(d); + else + translucentData.append(d); + } + + // horizontal edges + if (targetCenterWidth > 0 && sourceCenterWidth > 0) { + if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData; + d.sourceLeft = sourceCenterLeft; + d.sourceTop = sourceRect.top(); + d.width = sourceCenterWidth; + d.height = sourceMargins.top(); + d.y = (0.5 * (yTarget[1] + yTarget[0])); + d.scaleX = dx / d.width; + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; + for (int i = 1; i < columns - 1; ++i) { + d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); + } + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); + } + if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData; + d.sourceLeft = sourceCenterLeft; + d.sourceTop = sourceCenterBottom; + d.width = sourceCenterWidth; + d.height = sourceMargins.bottom(); + d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.scaleX = dx / d.width; + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; + for (int i = 1; i < columns - 1; ++i) { + d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); + } + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); + } + } + + // vertical edges + if (targetCenterHeight > 0 && sourceCenterHeight > 0) { + if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData; + d.sourceLeft = sourceRect.left(); + d.sourceTop = sourceCenterTop; + d.width = sourceMargins.left(); + d.height = sourceCenterHeight; + d.x = (0.5 * (xTarget[1] + xTarget[0])); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; + d.scaleY = dy / d.height; + for (int i = 1; i < rows - 1; ++i) { + d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); + data.append(d); + } + if (rules.vertical == Qt::RepeatTile) + data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); + } + if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData; + d.sourceLeft = sourceCenterRight; + d.sourceTop = sourceCenterTop; + d.width = sourceMargins.right(); + d.height = sourceCenterHeight; + d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; + d.scaleY = dy / d.height; + for (int i = 1; i < rows - 1; ++i) { + d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); + data.append(d); + } + if (rules.vertical == Qt::RepeatTile) + data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); + } + } + + // center + if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) { + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData; + d.sourceLeft = sourceCenterLeft; + d.sourceTop = sourceCenterTop; + d.width = sourceCenterWidth; + d.height = sourceCenterHeight; + d.scaleX = dx / d.width; + d.scaleY = dy / d.height; + + qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX; + qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY; + + for (int j = 1; j < rows - 1; ++j) { + d.y = (0.5 * (yTarget[j + 1] + yTarget[j])); + for (int i = 1; i < columns - 1; ++i) { + d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); + } + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].width = repeatWidth; + } + if (rules.vertical == Qt::RepeatTile) { + for (int i = 1; i < columns - 1; ++i) + data[data.size() - i].height = repeatHeight; + } + } + + if (opaqueData.size()) + painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint); + if (translucentData.size()) + painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap); + + if (oldAA) + painter->setRenderHint(QPainter::Antialiasing, true); +} + +} // QSGSoftwareHelpers namespace + +QSGSoftwareImageNode::QSGSoftwareImageNode() + : m_innerSourceRect(0, 0, 1, 1) + , m_subSourceRect(0, 0, 1, 1) + , m_texture(0) + , m_mirror(false) + , m_smooth(true) + , m_tileHorizontal(false) + , m_tileVertical(false) + , m_cachedMirroredPixmapIsDirty(false) +{ + setMaterial((QSGMaterial*)1); + setGeometry((QSGGeometry*)1); +} + + +void QSGSoftwareImageNode::setTargetRect(const QRectF &rect) +{ + if (rect == m_targetRect) + return; + m_targetRect = rect; + markDirty(DirtyGeometry); +} + +void QSGSoftwareImageNode::setInnerTargetRect(const QRectF &rect) +{ + if (rect == m_innerTargetRect) + return; + m_innerTargetRect = rect; + markDirty(DirtyGeometry); +} + +void QSGSoftwareImageNode::setInnerSourceRect(const QRectF &rect) +{ + if (rect == m_innerSourceRect) + return; + m_innerSourceRect = rect; + markDirty(DirtyGeometry); +} + +void QSGSoftwareImageNode::setSubSourceRect(const QRectF &rect) +{ + if (rect == m_subSourceRect) + return; + m_subSourceRect = rect; + markDirty(DirtyGeometry); +} + +void QSGSoftwareImageNode::setTexture(QSGTexture *texture) +{ + if (m_texture != texture) { + m_texture = texture; + m_cachedMirroredPixmapIsDirty = true; + markDirty(DirtyMaterial); + } +} + +void QSGSoftwareImageNode::setMirror(bool mirror) +{ + if (m_mirror != mirror) { + m_mirror = mirror; + m_cachedMirroredPixmapIsDirty = true; + markDirty(DirtyMaterial); + } +} + +void QSGSoftwareImageNode::setMipmapFiltering(QSGTexture::Filtering /*filtering*/) +{ +} + +void QSGSoftwareImageNode::setFiltering(QSGTexture::Filtering filtering) +{ + bool smooth = (filtering == QSGTexture::Linear); + if (smooth == m_smooth) + return; + + m_smooth = smooth; + markDirty(DirtyMaterial); +} + +void QSGSoftwareImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) +{ + bool tileHorizontal = (wrapMode == QSGTexture::Repeat); + if (tileHorizontal == m_tileHorizontal) + return; + + m_tileHorizontal = tileHorizontal; + markDirty(DirtyMaterial); +} + +void QSGSoftwareImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode) +{ + bool tileVertical = (wrapMode == QSGTexture::Repeat); + if (tileVertical == m_tileVertical) + return; + + m_tileVertical = (wrapMode == QSGTexture::Repeat); + markDirty(DirtyMaterial); +} + +void QSGSoftwareImageNode::update() +{ + if (m_cachedMirroredPixmapIsDirty) { + if (m_mirror) { + m_cachedMirroredPixmap = pixmap().transformed(QTransform(-1, 0, 0, 1, 0, 0)); + } else { + //Cleanup cached pixmap if necessary + if (!m_cachedMirroredPixmap.isNull()) + m_cachedMirroredPixmap = QPixmap(); + } + m_cachedMirroredPixmapIsDirty = false; + } +} + +void QSGSoftwareImageNode::preprocess() +{ + bool doDirty = false; + QSGLayer *t = qobject_cast<QSGLayer *>(m_texture); + if (t) { + doDirty = t->updateTexture(); + markDirty(DirtyGeometry); + } + if (doDirty) + markDirty(DirtyMaterial); +} + +static Qt::TileRule getTileRule(qreal factor) +{ + int ifactor = qRound(factor); + if (qFuzzyCompare(factor, ifactor )) { + if (ifactor == 1 || ifactor == 0) + return Qt::StretchTile; + return Qt::RoundTile; + } + return Qt::RepeatTile; +} + + +void QSGSoftwareImageNode::paint(QPainter *painter) +{ + painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); + + const QPixmap &pm = m_mirror ? m_cachedMirroredPixmap : pixmap(); + + if (m_innerTargetRect != m_targetRect) { + // border image + QMargins margins(m_innerTargetRect.left() - m_targetRect.left(), m_innerTargetRect.top() - m_targetRect.top(), + m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom()); + QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height())); + QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()), + margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(0)); + return; + } + + if (m_tileHorizontal || m_tileVertical) { + painter->save(); + qreal sx = m_targetRect.width()/(m_subSourceRect.width()*pm.width()); + qreal sy = m_targetRect.height()/(m_subSourceRect.height()*pm.height()); + QMatrix transform(sx, 0, 0, sy, 0, 0); + painter->setMatrix(transform, true); + painter->drawTiledPixmap(QRectF(m_targetRect.x()/sx, m_targetRect.y()/sy, m_targetRect.width()/sx, m_targetRect.height()/sy), + pm, + QPointF(m_subSourceRect.left()*pm.width(), m_subSourceRect.top()*pm.height())); + painter->restore(); + } else { + QRectF sr(m_subSourceRect.left()*pm.width(), m_subSourceRect.top()*pm.height(), + m_subSourceRect.width()*pm.width(), m_subSourceRect.height()*pm.height()); + painter->drawPixmap(m_targetRect, pm, sr); + } +} + +QRectF QSGSoftwareImageNode::rect() const +{ + return m_targetRect; +} + +const QPixmap &QSGSoftwareImageNode::pixmap() const +{ + if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(m_texture)) { + return pt->pixmap(); + } else { + QSGSoftwareLayer *layer = qobject_cast<QSGSoftwareLayer*>(m_texture); + return layer->pixmap(); + } +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareimagenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareimagenode_p.h new file mode 100644 index 0000000000..7f6c4481c4 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareimagenode_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWAREIMAGENODE_H +#define QSGSOFTWAREIMAGENODE_H + +#include <private/qsgadaptationlayer_p.h> +#include <private/qsgtexturematerial_p.h> + +QT_BEGIN_NAMESPACE + +namespace QSGSoftwareHelpers { + +typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray; + +struct QTileRules +{ + inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule) + : horizontal(horizontalRule), vertical(verticalRule) {} + inline QTileRules(Qt::TileRule rule = Qt::StretchTile) + : horizontal(rule), vertical(rule) {} + Qt::TileRule horizontal; + Qt::TileRule vertical; +}; + +#ifndef Q_QDOC +// For internal use only. +namespace QDrawBorderPixmap +{ + enum DrawingHint + { + OpaqueTopLeft = 0x0001, + OpaqueTop = 0x0002, + OpaqueTopRight = 0x0004, + OpaqueLeft = 0x0008, + OpaqueCenter = 0x0010, + OpaqueRight = 0x0020, + OpaqueBottomLeft = 0x0040, + OpaqueBottom = 0x0080, + OpaqueBottomRight = 0x0100, + OpaqueCorners = OpaqueTopLeft | OpaqueTopRight | OpaqueBottomLeft | OpaqueBottomRight, + OpaqueEdges = OpaqueTop | OpaqueLeft | OpaqueRight | OpaqueBottom, + OpaqueFrame = OpaqueCorners | OpaqueEdges, + OpaqueAll = OpaqueCenter | OpaqueFrame + }; + + Q_DECLARE_FLAGS(DrawingHints, DrawingHint) +} +#endif + +void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, + const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins, + const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints); + +} // QSGSoftwareHelpers namespace + +class QSGSoftwareImageNode : public QSGImageNode +{ +public: + QSGSoftwareImageNode(); + + void setTargetRect(const QRectF &rect) override; + void setInnerTargetRect(const QRectF &rect) override; + void setInnerSourceRect(const QRectF &rect) override; + void setSubSourceRect(const QRectF &rect) override; + void setTexture(QSGTexture *texture) override; + void setMirror(bool mirror) override; + void setMipmapFiltering(QSGTexture::Filtering filtering) override; + void setFiltering(QSGTexture::Filtering filtering) override; + void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) override; + void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) override; + void update() override; + + void preprocess() override; + + void paint(QPainter *painter); + + QRectF rect() const; + +private: + const QPixmap &pixmap() const; + + QRectF m_targetRect; + QRectF m_innerTargetRect; + QRectF m_innerSourceRect; + QRectF m_subSourceRect; + + QSGTexture *m_texture; + QPixmap m_cachedMirroredPixmap; + + bool m_mirror; + bool m_smooth; + bool m_tileHorizontal; + bool m_tileVertical; + bool m_cachedMirroredPixmapIsDirty; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWAREIMAGENODE_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp new file mode 100644 index 0000000000..7020283898 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarelayer_p.h" + +#include "qsgsoftwarecontext_p.h" +#include "qsgsoftwarepixmaprenderer_p.h" + +QT_BEGIN_NAMESPACE + +QSGSoftwareLayer::QSGSoftwareLayer(QSGRenderContext *renderContext) + : m_item(0) + , m_context(renderContext) + , m_renderer(0) + , m_device_pixel_ratio(1) + , m_mirrorHorizontal(false) + , m_mirrorVertical(false) + , m_live(true) + , m_grab(true) + , m_recursive(false) + , m_dirtyTexture(true) +{ + +} + +QSGSoftwareLayer::~QSGSoftwareLayer() +{ + invalidated(); +} + +int QSGSoftwareLayer::textureId() const +{ + return 0; +} + +QSize QSGSoftwareLayer::textureSize() const +{ + return m_pixmap.size(); +} + +bool QSGSoftwareLayer::hasAlphaChannel() const +{ + return m_pixmap.hasAlphaChannel(); +} + +bool QSGSoftwareLayer::hasMipmaps() const +{ + return false; +} + +void QSGSoftwareLayer::bind() +{ +} + +bool QSGSoftwareLayer::updateTexture() +{ + bool doGrab = (m_live || m_grab) && m_dirtyTexture; + if (doGrab) + grab(); + if (m_grab) + emit scheduledUpdateCompleted(); + m_grab = false; + return doGrab; +} + +void QSGSoftwareLayer::setItem(QSGNode *item) +{ + if (item == m_item) + return; + m_item = item; + + if (m_live && !m_item) + m_pixmap = QPixmap(); + + markDirtyTexture(); +} + +void QSGSoftwareLayer::setRect(const QRectF &rect) +{ + if (rect == m_rect) + return; + m_rect = rect; + markDirtyTexture(); +} + +void QSGSoftwareLayer::setSize(const QSize &size) +{ + if (size == m_size) + return; + m_size = size; + + if (m_live && m_size.isNull()) + m_pixmap = QPixmap(); + + markDirtyTexture(); +} + +void QSGSoftwareLayer::scheduleUpdate() +{ + if (m_grab) + return; + m_grab = true; + if (m_dirtyTexture) { + emit updateRequested(); + } +} + +QImage QSGSoftwareLayer::toImage() const +{ + return m_pixmap.toImage(); +} + +void QSGSoftwareLayer::setLive(bool live) +{ + if (live == m_live) + return; + m_live = live; + + if (m_live && (!m_item || m_size.isNull())) + m_pixmap = QPixmap(); + + markDirtyTexture(); +} + +void QSGSoftwareLayer::setRecursive(bool recursive) +{ + m_recursive = recursive; +} + +void QSGSoftwareLayer::setFormat(uint) +{ +} + +void QSGSoftwareLayer::setHasMipmaps(bool) +{ +} + +void QSGSoftwareLayer::setDevicePixelRatio(qreal ratio) +{ + m_device_pixel_ratio = ratio; +} + +void QSGSoftwareLayer::setMirrorHorizontal(bool mirror) +{ + if (m_mirrorHorizontal == mirror) + return; + m_mirrorHorizontal = mirror; + markDirtyTexture(); +} + +void QSGSoftwareLayer::setMirrorVertical(bool mirror) +{ + if (m_mirrorVertical == mirror) + return; + m_mirrorVertical = mirror; + markDirtyTexture(); +} + +void QSGSoftwareLayer::markDirtyTexture() +{ + m_dirtyTexture = true; + if (m_live || m_grab) { + emit updateRequested(); + } +} + +void QSGSoftwareLayer::invalidated() +{ + delete m_renderer; + m_renderer = 0; +} + +void QSGSoftwareLayer::grab() +{ + if (!m_item || m_size.isNull()) { + m_pixmap = QPixmap(); + m_dirtyTexture = false; + return; + } + QSGNode *root = m_item; + while (root->firstChild() && root->type() != QSGNode::RootNodeType) + root = root->firstChild(); + if (root->type() != QSGNode::RootNodeType) + return; + + if (!m_renderer) { + m_renderer = new QSGSoftwarePixmapRenderer(m_context); + connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture())); + } + m_renderer->setDevicePixelRatio(m_device_pixel_ratio); + m_renderer->setRootNode(static_cast<QSGRootNode *>(root)); + + if (m_pixmap.size() != m_size) { + m_pixmap = QPixmap(m_size); + m_pixmap.setDevicePixelRatio(m_device_pixel_ratio); + // This fill here is wasteful, but necessary because it is the only way + // to force a QImage based pixmap to have an alpha channel. + m_pixmap.fill(Qt::transparent); + } + + // Render texture. + root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update. + m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update. + + m_dirtyTexture = false; + + m_renderer->setDeviceRect(m_size); + m_renderer->setViewportRect(m_size); + QRect mirrored(m_mirrorHorizontal ? m_rect.right() * m_device_pixel_ratio : m_rect.left() * m_device_pixel_ratio, + m_mirrorVertical ? m_rect.top() * m_device_pixel_ratio : m_rect.bottom() * m_device_pixel_ratio, + m_mirrorHorizontal ? -m_rect.width() * m_device_pixel_ratio : m_rect.width() * m_device_pixel_ratio, + m_mirrorVertical ? m_rect.height() * m_device_pixel_ratio : -m_rect.height() * m_device_pixel_ratio); + m_renderer->setProjectionRect(mirrored); + m_renderer->setClearColor(Qt::transparent); + + m_renderer->renderScene(); + m_renderer->render(&m_pixmap); + + root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update. + + if (m_recursive) + markDirtyTexture(); // Continuously update if 'live' and 'recursive'. +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h new file mode 100644 index 0000000000..7c0027d3a2 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARELAYER_H +#define QSGSOFTWARELAYER_H + +#include <private/qsgadaptationlayer_p.h> +#include <private/qsgcontext_p.h> + +QT_BEGIN_NAMESPACE + +class QSGSoftwarePixmapRenderer; + +class QSGSoftwareLayer : public QSGLayer +{ + Q_OBJECT +public: + QSGSoftwareLayer(QSGRenderContext *renderContext); + ~QSGSoftwareLayer(); + + const QPixmap &pixmap() const { return m_pixmap; } + + // QSGTexture interface +public: + int textureId() const override; + QSize textureSize() const override; + bool hasAlphaChannel() const override; + bool hasMipmaps() const override; + void bind() override; + + // QSGDynamicTexture interface +public: + bool updateTexture() override; + + // QSGLayer interface +public: + void setItem(QSGNode *item) override; + void setRect(const QRectF &rect) override; + void setSize(const QSize &size) override; + void scheduleUpdate() override; + QImage toImage() const override; + void setLive(bool live) override; + void setRecursive(bool recursive) override; + void setFormat(uint) override; + void setHasMipmaps(bool) override; + void setDevicePixelRatio(qreal ratio) override; + void setMirrorHorizontal(bool mirror) override; + void setMirrorVertical(bool mirror) override; + +public slots: + void markDirtyTexture() override; + void invalidated() override; + +private: + void grab(); + + QSGNode *m_item; + QSGRenderContext *m_context; + QSGSoftwarePixmapRenderer *m_renderer; + QRectF m_rect; + QSize m_size; + QPixmap m_pixmap; + qreal m_device_pixel_ratio; + bool m_mirrorHorizontal; + bool m_mirrorVertical; + bool m_live; + bool m_grab; + bool m_recursive; + bool m_dirtyTexture; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWARELAYER_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode.cpp new file mode 100644 index 0000000000..36ff1f2229 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwareninepatchnode_p.h" +#include "qsgsoftwarepixmaptexture_p.h" +#include "qsgsoftwareimagenode_p.h" + +QT_BEGIN_NAMESPACE + +QSGSoftwareNinePatchNode::QSGSoftwareNinePatchNode() +{ + setMaterial((QSGMaterial*)1); + setGeometry((QSGGeometry*)1); +} + +void QSGSoftwareNinePatchNode::setTexture(QSGTexture *texture) +{ + QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(texture); + if (!pt) { + qWarning() << "Image used with invalid texture format."; + return; + } + m_pixmap = pt->pixmap(); + markDirty(DirtyMaterial); +} + +void QSGSoftwareNinePatchNode::setBounds(const QRectF &bounds) +{ + if (m_bounds == bounds) + return; + + m_bounds = bounds; + markDirty(DirtyGeometry); +} + +void QSGSoftwareNinePatchNode::setDevicePixelRatio(qreal ratio) +{ + if (m_pixelRatio == ratio) + return; + + m_pixelRatio = ratio; + markDirty(DirtyGeometry); +} + +void QSGSoftwareNinePatchNode::setPadding(qreal left, qreal top, qreal right, qreal bottom) +{ + QMargins margins(qRound(left), qRound(top), qRound(right), qRound(bottom)); + if (m_margins == margins) + return; + + m_margins = QMargins(qRound(left), qRound(top), qRound(right), qRound(bottom)); + markDirty(DirtyGeometry); +} + +void QSGSoftwareNinePatchNode::update() +{ +} + +void QSGSoftwareNinePatchNode::paint(QPainter *painter) +{ + if (m_margins.isNull()) + painter->drawPixmap(m_bounds, m_pixmap, QRectF(0, 0, m_pixmap.width(), m_pixmap.height())); + else + QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_bounds.toRect(), m_margins, m_pixmap, QRect(0, 0, m_pixmap.width(), m_pixmap.height()), + m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(0)); +} + +QRectF QSGSoftwareNinePatchNode::bounds() const +{ + return m_bounds; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode_p.h new file mode 100644 index 0000000000..68db5e1284 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARENINEPATCHNODE_H +#define QSGSOFTWARENINEPATCHNODE_H + +#include <private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +class QSGSoftwareNinePatchNode : public QSGNinePatchNode +{ +public: + QSGSoftwareNinePatchNode(); + + void setTexture(QSGTexture *texture) override; + void setBounds(const QRectF &bounds) override; + void setDevicePixelRatio(qreal ratio) override; + void setPadding(qreal left, qreal top, qreal right, qreal bottom) override; + void update() override; + + void paint(QPainter *painter); + + QRectF bounds() const; + +private: + QPixmap m_pixmap; + QRectF m_bounds; + qreal m_pixelRatio; + QMargins m_margins; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWARENINEPATCHNODE_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp new file mode 100644 index 0000000000..34b0cd5b72 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarepainternode_p.h" +#include "qsgsoftwarepixmaptexture_p.h" +#include <qmath.h> + +QT_BEGIN_NAMESPACE + +QSGSoftwarePainterNode::QSGSoftwarePainterNode(QQuickPaintedItem *item) + : QSGPainterNode() + , m_preferredRenderTarget(QQuickPaintedItem::Image) + , m_item(item) + , m_texture(0) + , m_dirtyContents(false) + , m_opaquePainting(false) + , m_linear_filtering(false) + , m_mipmapping(false) + , m_smoothPainting(false) + , m_fastFBOResizing(false) + , m_fillColor(Qt::transparent) + , m_contentsScale(1.0) + , m_dirtyGeometry(false) +{ + setMaterial((QSGMaterial*)1); + setGeometry((QSGGeometry*)1); +} + +QSGSoftwarePainterNode::~QSGSoftwarePainterNode() +{ + delete m_texture; +} + +void QSGSoftwarePainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) +{ + if (m_preferredRenderTarget == target) + return; + + m_preferredRenderTarget = target; +} + +void QSGSoftwarePainterNode::setSize(const QSize &size) +{ + if (size == m_size) + return; + + m_size = size; + + m_dirtyGeometry = true; +} + +void QSGSoftwarePainterNode::setDirty(const QRect &dirtyRect) +{ + m_dirtyContents = true; + m_dirtyRect = dirtyRect; + markDirty(DirtyMaterial); +} + +void QSGSoftwarePainterNode::setOpaquePainting(bool opaque) +{ + if (opaque == m_opaquePainting) + return; + + m_opaquePainting = opaque; +} + +void QSGSoftwarePainterNode::setLinearFiltering(bool linearFiltering) +{ + if (linearFiltering == m_linear_filtering) + return; + + m_linear_filtering = linearFiltering; +} + +void QSGSoftwarePainterNode::setMipmapping(bool mipmapping) +{ + if (mipmapping == m_mipmapping) + return; + + m_mipmapping = mipmapping; +} + +void QSGSoftwarePainterNode::setSmoothPainting(bool s) +{ + if (s == m_smoothPainting) + return; + + m_smoothPainting = s; +} + +void QSGSoftwarePainterNode::setFillColor(const QColor &c) +{ + if (c == m_fillColor) + return; + + m_fillColor = c; + markDirty(DirtyMaterial); +} + +void QSGSoftwarePainterNode::setContentsScale(qreal s) +{ + if (s == m_contentsScale) + return; + + m_contentsScale = s; + markDirty(DirtyMaterial); +} + +void QSGSoftwarePainterNode::setFastFBOResizing(bool dynamic) +{ + m_fastFBOResizing = dynamic; +} + +QImage QSGSoftwarePainterNode::toImage() const +{ + return m_pixmap.toImage(); +} + +void QSGSoftwarePainterNode::update() +{ + if (m_dirtyGeometry) { + m_pixmap = QPixmap(m_textureSize); + if (!m_opaquePainting) + m_pixmap.fill(Qt::transparent); + + if (m_texture) + delete m_texture; + m_texture = new QSGSoftwarePixmapTexture(m_pixmap); + } + + if (m_dirtyContents) + paint(); + + m_dirtyGeometry = false; + m_dirtyContents = false; +} + +void QSGSoftwarePainterNode::paint(QPainter *painter) +{ + painter->drawPixmap(0, 0, m_size.width(), m_size.height(), m_pixmap); +} + +void QSGSoftwarePainterNode::paint() +{ + QRect dirtyRect = m_dirtyRect.isNull() ? QRect(0, 0, m_size.width(), m_size.height()) : m_dirtyRect; + + QPainter painter; + + painter.begin(&m_pixmap); + if (m_smoothPainting) { + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); + } + + QRect clipRect; + + if (m_contentsScale == 1) { + qreal scaleX = m_textureSize.width() / (qreal) m_size.width(); + qreal scaleY = m_textureSize.height() / (qreal) m_size.height(); + painter.scale(scaleX, scaleY); + clipRect = dirtyRect; + } else { + painter.scale(m_contentsScale, m_contentsScale); + + QRect sclip(qFloor(dirtyRect.x()/m_contentsScale), + qFloor(dirtyRect.y()/m_contentsScale), + qCeil(dirtyRect.width()/m_contentsScale+dirtyRect.x()/m_contentsScale-qFloor(dirtyRect.x()/m_contentsScale)), + qCeil(dirtyRect.height()/m_contentsScale+dirtyRect.y()/m_contentsScale-qFloor(dirtyRect.y()/m_contentsScale))); + + clipRect = sclip; + } + + if (!m_dirtyRect.isNull()) + painter.setClipRect(clipRect); + + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(clipRect, m_fillColor); + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + + m_item->paint(&painter); + painter.end(); + + m_dirtyRect = QRect(); +} + + +void QSGSoftwarePainterNode::setTextureSize(const QSize &size) +{ + if (size == m_textureSize) + return; + + m_textureSize = size; + m_dirtyGeometry = true; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode_p.h new file mode 100644 index 0000000000..78ecc26868 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWAREPAINTERNODE_H +#define QSGSOFTWAREPAINTERNODE_H + +#include <private/qsgadaptationlayer_p.h> +#include <QtQuick/qquickpainteditem.h> + +#include <QtGui/QPixmap> + +QT_BEGIN_NAMESPACE + +class QSGSoftwarePainterNode : public QSGPainterNode +{ +public: + QSGSoftwarePainterNode(QQuickPaintedItem *item); + ~QSGSoftwarePainterNode(); + + void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) override; + + void setSize(const QSize &size) override; + QSize size() const { return m_size; } + + void setDirty(const QRect &dirtyRect = QRect()) override; + + void setOpaquePainting(bool opaque) override; + bool opaquePainting() const { return m_opaquePainting; } + + void setLinearFiltering(bool linearFiltering) override; + bool linearFiltering() const { return m_linear_filtering; } + + void setMipmapping(bool mipmapping) override; + bool mipmapping() const { return m_mipmapping; } + + void setSmoothPainting(bool s) override; + bool smoothPainting() const { return m_smoothPainting; } + + void setFillColor(const QColor &c) override; + QColor fillColor() const { return m_fillColor; } + + void setContentsScale(qreal s) override; + qreal contentsScale() const { return m_contentsScale; } + + void setFastFBOResizing(bool dynamic) override; + bool fastFBOResizing() const { return m_fastFBOResizing; } + + QImage toImage() const override; + void update() override; + QSGTexture *texture() const override { return m_texture; } + + void paint(QPainter *painter); + + void paint(); + + void setTextureSize(const QSize &size) override; + QSize textureSize() const { return m_textureSize; } + +private: + + QQuickPaintedItem::RenderTarget m_preferredRenderTarget; + + QQuickPaintedItem *m_item; + + QPixmap m_pixmap; + QSGTexture *m_texture; + + QSize m_size; + bool m_dirtyContents; + QRect m_dirtyRect; + bool m_opaquePainting; + bool m_linear_filtering; + bool m_mipmapping; + bool m_smoothPainting; + bool m_fastFBOResizing; + QColor m_fillColor; + qreal m_contentsScale; + QSize m_textureSize; + + bool m_dirtyGeometry; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWAREPAINTERNODE_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp new file mode 100644 index 0000000000..acc55bb2db --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarepixmaprenderer_p.h" + +#include <QtQuick/QSGSimpleRectNode> + +#include <QElapsedTimer> + +Q_LOGGING_CATEGORY(lcPixmapRenderer, "qt.scenegraph.softwarecontext.pixmapRenderer") + +QT_BEGIN_NAMESPACE + +QSGSoftwarePixmapRenderer::QSGSoftwarePixmapRenderer(QSGRenderContext *context) + : QSGAbstractSoftwareRenderer(context) +{ + +} + +QSGSoftwarePixmapRenderer::~QSGSoftwarePixmapRenderer() +{ + +} + +void QSGSoftwarePixmapRenderer::renderScene(uint) +{ + class B : public QSGBindable + { + public: + void bind() const { } + } bindable; + QSGRenderer::renderScene(bindable); +} + +void QSGSoftwarePixmapRenderer::render() +{ + +} + +void QSGSoftwarePixmapRenderer::render(QPixmap *target) +{ + QElapsedTimer renderTimer; + + // Setup background item + setBackgroundSize(target->size()); + setBackgroundColor(clearColor()); + + QPainter painter(target); + painter.setRenderHint(QPainter::Antialiasing); + painter.setWindow(m_projectionRect); + + renderTimer.start(); + buildRenderList(); + qint64 buildRenderListTime = renderTimer.restart(); + + // Optimize Renderlist + // Right now there is an assumption that when possible the same pixmap will + // be reused. So we can treat it like a backing store in that we can assume + // that when the pixmap is not being resized, the data can be reused. What is + // different though is that everything should be marked as dirty on a resize. + optimizeRenderList(); + qint64 optimizeRenderListTime = renderTimer.restart(); + + QRegion paintedRegion = renderNodes(&painter); + qint64 renderTime = renderTimer.elapsed(); + + qCDebug(lcPixmapRenderer) << "pixmapRender" << paintedRegion << buildRenderListTime << optimizeRenderListTime << renderTime; +} + +void QSGSoftwarePixmapRenderer::setProjectionRect(const QRect &projectionRect) +{ + m_projectionRect = projectionRect; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h new file mode 100644 index 0000000000..1c4cff06da --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWAREPIXMAPRENDERER_H +#define QSGSOFTWAREPIXMAPRENDERER_H + +#include "qsgabstractsoftwarerenderer_p.h" + +QT_BEGIN_NAMESPACE + +class QSGSoftwarePixmapRenderer : public QSGAbstractSoftwareRenderer +{ +public: + QSGSoftwarePixmapRenderer(QSGRenderContext *context); + virtual ~QSGSoftwarePixmapRenderer(); + + void renderScene(uint fboId = 0) final; + void render() final; + + void render(QPixmap *target); + void setProjectionRect(const QRect &projectionRect); + +private: + QRect m_projectionRect; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWAREPIXMAPRENDERER_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp new file mode 100644 index 0000000000..e04c400af3 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarepixmaptexture_p.h" + +QT_BEGIN_NAMESPACE + +QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QImage &image) + // Prevent pixmap format conversion to reduce memory consumption + // and surprises in calling code. (See QTBUG-47328) + : m_pixmap(QPixmap::fromImage(image, Qt::NoFormatConversion)) +{ +} + +QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QPixmap &pixmap) + : m_pixmap(pixmap) +{ +} + + +int QSGSoftwarePixmapTexture::textureId() const +{ + return 0; +} + +QSize QSGSoftwarePixmapTexture::textureSize() const +{ + return m_pixmap.size(); +} + +bool QSGSoftwarePixmapTexture::hasAlphaChannel() const +{ + return m_pixmap.hasAlphaChannel(); +} + +bool QSGSoftwarePixmapTexture::hasMipmaps() const +{ + return false; +} + +void QSGSoftwarePixmapTexture::bind() +{ + Q_UNREACHABLE(); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h new file mode 100644 index 0000000000..0ddbadedae --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWAREPIXMAPTEXTURE_H +#define QSGSOFTWAREPIXMAPTEXTURE_H + +#include <private/qsgtexture_p.h> + +QT_BEGIN_NAMESPACE + +class QSGSoftwarePixmapTexture : public QSGTexture +{ + Q_OBJECT +public: + QSGSoftwarePixmapTexture(const QImage &image); + QSGSoftwarePixmapTexture(const QPixmap &pixmap); + + int textureId() const override; + QSize textureSize() const override; + bool hasAlphaChannel() const override; + bool hasMipmaps() const override; + void bind() override; + + const QPixmap &pixmap() const { return m_pixmap; } + +private: + QPixmap m_pixmap; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWAREPIXMAPTEXTURE_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerectanglenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerectanglenode.cpp new file mode 100644 index 0000000000..4acb25204e --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerectanglenode.cpp @@ -0,0 +1,452 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarerectanglenode_p.h" +#include <qmath.h> + +#include <QtGui/QPainter> + +QT_BEGIN_NAMESPACE + +QSGSoftwareRectangleNode::QSGSoftwareRectangleNode() + : m_penWidth(0) + , m_radius(0) + , m_cornerPixmapIsDirty(true) + , m_devicePixelRatio(1) +{ + m_pen.setJoinStyle(Qt::MiterJoin); + m_pen.setMiterLimit(0); + setMaterial((QSGMaterial*)1); + setGeometry((QSGGeometry*)1); +} + +void QSGSoftwareRectangleNode::setRect(const QRectF &rect) +{ + QRect alignedRect = rect.toAlignedRect(); + if (m_rect != alignedRect) { + m_rect = alignedRect; + markDirty(DirtyMaterial); + } +} + +void QSGSoftwareRectangleNode::setColor(const QColor &color) +{ + if (m_color != color) { + m_color = color; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); + } +} + +void QSGSoftwareRectangleNode::setPenColor(const QColor &color) +{ + if (m_penColor != color) { + m_penColor = color; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); + } +} + +void QSGSoftwareRectangleNode::setPenWidth(qreal width) +{ + if (m_penWidth != width) { + m_penWidth = width; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); + } +} + +//Move first stop by pos relative to seconds +static QGradientStop interpolateStop(const QGradientStop &firstStop, const QGradientStop &secondStop, double newPos) +{ + double distance = secondStop.first - firstStop.first; + double distanceDelta = newPos - firstStop.first; + double modifierValue = distanceDelta / distance; + int redDelta = (secondStop.second.red() - firstStop.second.red()) * modifierValue; + int greenDelta = (secondStop.second.green() - firstStop.second.green()) * modifierValue; + int blueDelta = (secondStop.second.blue() - firstStop.second.blue()) * modifierValue; + int alphaDelta = (secondStop.second.alpha() - firstStop.second.alpha()) * modifierValue; + + QGradientStop newStop; + newStop.first = newPos; + newStop.second = QColor(firstStop.second.red() + redDelta, + firstStop.second.green() + greenDelta, + firstStop.second.blue() + blueDelta, + firstStop.second.alpha() + alphaDelta); + + return newStop; +} + +void QSGSoftwareRectangleNode::setGradientStops(const QGradientStops &stops) +{ + //normalize stops + bool needsNormalization = false; + foreach (const QGradientStop &stop, stops) { + if (stop.first < 0.0 || stop.first > 1.0) { + needsNormalization = true; + continue; + } + } + + if (needsNormalization) { + QGradientStops normalizedStops; + if (stops.count() == 1) { + //If there is only one stop, then the position does not matter + //It is just treated as a color + QGradientStop stop = stops.at(0); + stop.first = 0.0; + normalizedStops.append(stop); + } else { + //Clip stops to only the first below 0.0 and above 1.0 + int below = -1; + int above = -1; + QVector<int> between; + for (int i = 0; i < stops.count(); ++i) { + if (stops.at(i).first < 0.0) { + below = i; + } else if (stops.at(i).first > 1.0) { + above = i; + break; + } else { + between.append(i); + } + } + + //Interpoloate new color values for above and below + if (below != -1 ) { + //If there are more than one stops left, interpolate + if (below + 1 < stops.count()) { + normalizedStops.append(interpolateStop(stops.at(below), stops.at(below + 1), 0.0)); + } else { + QGradientStop singleStop; + singleStop.first = 0.0; + singleStop.second = stops.at(below).second; + normalizedStops.append(singleStop); + } + } + + for (int i = 0; i < between.count(); ++i) + normalizedStops.append(stops.at(between.at(i))); + + if (above != -1) { + //If there stops before above, interpolate + if (above >= 1) { + normalizedStops.append(interpolateStop(stops.at(above), stops.at(above - 1), 1.0)); + } else { + QGradientStop singleStop; + singleStop.first = 1.0; + singleStop.second = stops.at(above).second; + normalizedStops.append(singleStop); + } + } + } + + m_stops = normalizedStops; + + } else { + m_stops = stops; + } + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); +} + +void QSGSoftwareRectangleNode::setRadius(qreal radius) +{ + if (m_radius != radius) { + m_radius = radius; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); + } +} + +void QSGSoftwareRectangleNode::setAligned(bool /*aligned*/) +{ +} + +void QSGSoftwareRectangleNode::update() +{ + if (!m_penWidth || m_penColor == Qt::transparent) { + m_pen = Qt::NoPen; + } else { + m_pen = QPen(m_penColor); + m_pen.setWidthF(m_penWidth); + } + + if (!m_stops.isEmpty()) { + QLinearGradient gradient(QPoint(0,0), QPoint(0,1)); + gradient.setStops(m_stops); + gradient.setCoordinateMode(QGradient::ObjectBoundingMode); + m_brush = QBrush(gradient); + } else { + m_brush = QBrush(m_color); + } + + if (m_cornerPixmapIsDirty) { + generateCornerPixmap(); + m_cornerPixmapIsDirty = false; + } +} + +void QSGSoftwareRectangleNode::paint(QPainter *painter) +{ + //We can only check for a device pixel ratio change when we know what + //paint device is being used. + if (painter->device()->devicePixelRatio() != m_devicePixelRatio) { + m_devicePixelRatio = painter->device()->devicePixelRatio(); + generateCornerPixmap(); + } + + if (painter->transform().isRotating()) { + //Rotated rectangles lose the benefits of direct rendering, and have poor rendering + //quality when using only blits and fills. + + if (m_radius == 0 && m_penWidth == 0) { + //Non-Rounded Rects without borders (fall back to drawRect) + //Most common case + painter->setPen(Qt::NoPen); + painter->setBrush(m_brush); + painter->drawRect(m_rect); + } else { + //Rounded Rects and Rects with Borders + //Avoids broken behaviors of QPainter::drawRect/roundedRect + QPixmap pixmap = QPixmap(m_rect.width() * m_devicePixelRatio, m_rect.height() * m_devicePixelRatio); + pixmap.fill(Qt::transparent); + pixmap.setDevicePixelRatio(m_devicePixelRatio); + QPainter pixmapPainter(&pixmap); + paintRectangle(&pixmapPainter, QRect(0, 0, m_rect.width(), m_rect.height())); + + QPainter::RenderHints previousRenderHints = painter->renderHints(); + painter->setRenderHint(QPainter::SmoothPixmapTransform, true); + painter->drawPixmap(m_rect, pixmap); + painter->setRenderHints(previousRenderHints); + } + + + } else { + //Paint directly + paintRectangle(painter, m_rect); + } + +} + +bool QSGSoftwareRectangleNode::isOpaque() const +{ + if (m_radius > 0.0f) + return false; + if (m_color.alpha() < 255) + return false; + if (m_penWidth > 0.0f && m_penColor.alpha() < 255) + return false; + if (m_stops.count() > 0) { + foreach (QGradientStop stop, m_stops) { + if (stop.second.alpha() < 255) + return false; + } + } + + return true; +} + +QRectF QSGSoftwareRectangleNode::rect() const +{ + //TODO: double check that this is correct. + return m_rect; +} + +void QSGSoftwareRectangleNode::paintRectangle(QPainter *painter, const QRect &rect) +{ + //Radius should never exceeds half of the width or half of the height + int radius = qFloor(qMin(qMin(rect.width(), rect.height()) * 0.5, m_radius)); + + QPainter::RenderHints previousRenderHints = painter->renderHints(); + painter->setRenderHint(QPainter::Antialiasing, false); + + if (m_penWidth > 0) { + //Fill border Rects + + //Borders can not be more than half the height/width of a rect + double borderWidth = qMin(m_penWidth, rect.width() * 0.5); + double borderHeight = qMin(m_penWidth, rect.height() * 0.5); + + + + if (borderWidth > radius) { + //4 Rects + QRectF borderTopOutside(QPointF(rect.x() + radius, rect.y()), + QPointF(rect.x() + rect.width() - radius, rect.y() + radius)); + QRectF borderTopInside(QPointF(rect.x() + borderWidth, rect.y() + radius), + QPointF(rect.x() + rect.width() - borderWidth, rect.y() + borderHeight)); + QRectF borderBottomOutside(QPointF(rect.x() + radius, rect.y() + rect.height() - radius), + QPointF(rect.x() + rect.width() - radius, rect.y() + rect.height())); + QRectF borderBottomInside(QPointF(rect.x() + borderWidth, rect.y() + rect.height() - borderHeight), + QPointF(rect.x() + rect.width() - borderWidth, rect.y() + rect.height() - radius)); + + if (borderTopOutside.isValid()) + painter->fillRect(borderTopOutside, m_penColor); + if (borderTopInside.isValid()) + painter->fillRect(borderTopInside, m_penColor); + if (borderBottomOutside.isValid()) + painter->fillRect(borderBottomOutside, m_penColor); + if (borderBottomInside.isValid()) + painter->fillRect(borderBottomInside, m_penColor); + + } else { + //2 Rects + QRectF borderTop(QPointF(rect.x() + radius, rect.y()), + QPointF(rect.x() + rect.width() - radius, rect.y() + borderHeight)); + QRectF borderBottom(QPointF(rect.x() + radius, rect.y() + rect.height() - borderHeight), + QPointF(rect.x() + rect.width() - radius, rect.y() + rect.height())); + if (borderTop.isValid()) + painter->fillRect(borderTop, m_penColor); + if (borderBottom.isValid()) + painter->fillRect(borderBottom, m_penColor); + } + QRectF borderLeft(QPointF(rect.x(), rect.y() + radius), + QPointF(rect.x() + borderWidth, rect.y() + rect.height() - radius)); + QRectF borderRight(QPointF(rect.x() + rect.width() - borderWidth, rect.y() + radius), + QPointF(rect.x() + rect.width(), rect.y() + rect.height() - radius)); + if (borderLeft.isValid()) + painter->fillRect(borderLeft, m_penColor); + if (borderRight.isValid()) + painter->fillRect(borderRight, m_penColor); + } + + + if (radius > 0) { + + if (radius * 2 >= rect.width() && radius * 2 >= rect.height()) { + //Blit whole pixmap for circles + painter->drawPixmap(rect, m_cornerPixmap, m_cornerPixmap.rect()); + } else { + + //blit 4 corners to border + int scaledRadius = radius * m_devicePixelRatio; + QRectF topLeftCorner(QPointF(rect.x(), rect.y()), + QPointF(rect.x() + radius, rect.y() + radius)); + painter->drawPixmap(topLeftCorner, m_cornerPixmap, QRectF(0, 0, scaledRadius, scaledRadius)); + QRectF topRightCorner(QPointF(rect.x() + rect.width() - radius, rect.y()), + QPointF(rect.x() + rect.width(), rect.y() + radius)); + painter->drawPixmap(topRightCorner, m_cornerPixmap, QRectF(scaledRadius, 0, scaledRadius, scaledRadius)); + QRectF bottomLeftCorner(QPointF(rect.x(), rect.y() + rect.height() - radius), + QPointF(rect.x() + radius, rect.y() + rect.height())); + painter->drawPixmap(bottomLeftCorner, m_cornerPixmap, QRectF(0, scaledRadius, scaledRadius, scaledRadius)); + QRectF bottomRightCorner(QPointF(rect.x() + rect.width() - radius, rect.y() + rect.height() - radius), + QPointF(rect.x() + rect.width(), rect.y() + rect.height())); + painter->drawPixmap(bottomRightCorner, m_cornerPixmap, QRectF(scaledRadius, scaledRadius, scaledRadius, scaledRadius)); + + } + + } + + int penWidth = qRound(m_penWidth); + QRectF brushRect = rect.marginsRemoved(QMargins(penWidth, penWidth, penWidth, penWidth)); + if (brushRect.width() < 0) + brushRect.setWidth(0); + if (brushRect.height() < 0) + brushRect.setHeight(0); + double innerRectRadius = qMax(0.0, radius - m_penWidth); + + //If not completely transparent or has a gradient + if (m_color.alpha() > 0 || !m_stops.empty()) { + if (innerRectRadius > 0) { + //Rounded Rect + if (m_stops.empty()) { + //Rounded Rects without gradient need 3 blits + QRectF centerRect(QPointF(brushRect.x() + innerRectRadius, brushRect.y()), + QPointF(brushRect.x() + brushRect.width() - innerRectRadius, brushRect.y() + brushRect.height())); + painter->fillRect(centerRect, m_color); + QRectF leftRect(QPointF(brushRect.x(), brushRect.y() + innerRectRadius), + QPointF(brushRect.x() + innerRectRadius, brushRect.y() + brushRect.height() - innerRectRadius)); + painter->fillRect(leftRect, m_color); + QRectF rightRect(QPointF(brushRect.x() + brushRect.width() - innerRectRadius, brushRect.y() + innerRectRadius), + QPointF(brushRect.x() + brushRect.width(), brushRect.y() + brushRect.height() - innerRectRadius)); + painter->fillRect(rightRect, m_color); + } else { + //Rounded Rect with gradient (slow) + painter->setPen(Qt::NoPen); + painter->setBrush(m_brush); + painter->drawRoundedRect(brushRect, innerRectRadius, innerRectRadius); + } + } else { + //non-rounded rects only need 1 blit + painter->fillRect(brushRect, m_brush); + } + } + + painter->setRenderHints(previousRenderHints); +} + +void QSGSoftwareRectangleNode::generateCornerPixmap() +{ + //Generate new corner Pixmap + int radius = qFloor(qMin(qMin(m_rect.width(), m_rect.height()) * 0.5, m_radius)); + + m_cornerPixmap = QPixmap(radius * 2 * m_devicePixelRatio, radius * 2 * m_devicePixelRatio); + m_cornerPixmap.setDevicePixelRatio(m_devicePixelRatio); + m_cornerPixmap.fill(Qt::transparent); + + if (radius > 0) { + QPainter cornerPainter(&m_cornerPixmap); + cornerPainter.setRenderHint(QPainter::Antialiasing); + cornerPainter.setCompositionMode(QPainter::CompositionMode_Source); + + //Paint outer cicle + if (m_penWidth > 0) { + cornerPainter.setPen(Qt::NoPen); + cornerPainter.setBrush(m_penColor); + cornerPainter.drawRoundedRect(QRectF(0, 0, radius * 2, radius *2), radius, radius); + } + + //Paint inner circle + if (radius > m_penWidth) { + cornerPainter.setPen(Qt::NoPen); + if (m_stops.isEmpty()) + cornerPainter.setBrush(m_brush); + else + cornerPainter.setBrush(Qt::transparent); + + QMarginsF adjustmentMargins(m_penWidth, m_penWidth, m_penWidth, m_penWidth); + QRectF cornerCircleRect = QRectF(0, 0, radius * 2, radius * 2).marginsRemoved(adjustmentMargins); + cornerPainter.drawRoundedRect(cornerCircleRect, radius, radius); + } + cornerPainter.end(); + } +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerectanglenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerectanglenode_p.h new file mode 100644 index 0000000000..3af3b39aac --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerectanglenode_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARERECTANGLENODE_H +#define QSGSOFTWARERECTANGLENODE_H + +#include <private/qsgadaptationlayer_p.h> + +#include <QPen> +#include <QBrush> +#include <QPixmap> + +QT_BEGIN_NAMESPACE + +class QSGSoftwareRectangleNode : public QSGRectangleNode +{ +public: + QSGSoftwareRectangleNode(); + + void setRect(const QRectF &rect) override; + void setColor(const QColor &color) override; + void setPenColor(const QColor &color) override; + void setPenWidth(qreal width) override; + void setGradientStops(const QGradientStops &stops) override; + void setRadius(qreal radius) override; + void setAntialiasing(bool antialiasing) override { Q_UNUSED(antialiasing) } + void setAligned(bool aligned) override; + + void update() override; + + void paint(QPainter *); + + bool isOpaque() const; + QRectF rect() const; +private: + void paintRectangle(QPainter *painter, const QRect &rect); + void generateCornerPixmap(); + + QRect m_rect; + QColor m_color; + QColor m_penColor; + double m_penWidth; + QGradientStops m_stops; + double m_radius; + QPen m_pen; + QBrush m_brush; + + bool m_cornerPixmapIsDirty; + QPixmap m_cornerPixmap; + + int m_devicePixelRatio; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWARERECTANGLENODE_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp new file mode 100644 index 0000000000..65cce805a4 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp @@ -0,0 +1,323 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarerenderablenode_p.h" + +#include "qsgsoftwareimagenode_p.h" +#include "qsgsoftwarerectanglenode_p.h" +#include "qsgsoftwareglyphnode_p.h" +#include "qsgsoftwareninepatchnode_p.h" +#include "qsgsoftwarepainternode_p.h" +#include "qsgsoftwarepixmaptexture_p.h" + +#include <QtQuick/QSGSimpleRectNode> +#include <QtQuick/qsgsimpletexturenode.h> +#include <private/qsgtexture_p.h> + +Q_LOGGING_CATEGORY(lcRenderable, "qt.scenegraph.softwarecontext.renderable") + +QT_BEGIN_NAMESPACE + +QSGSoftwareRenderableNode::QSGSoftwareRenderableNode(NodeType type, QSGNode *node) + : m_nodeType(type) + , m_isOpaque(true) + , m_isDirty(true) + , m_opacity(1.0f) +{ + switch (m_nodeType) { + case QSGSoftwareRenderableNode::SimpleRect: + m_handle.simpleRectNode = static_cast<QSGSimpleRectNode*>(node); + break; + case QSGSoftwareRenderableNode::SimpleTexture: + m_handle.simpleTextureNode = static_cast<QSGSimpleTextureNode*>(node); + break; + case QSGSoftwareRenderableNode::Image: + m_handle.imageNode = static_cast<QSGSoftwareImageNode*>(node); + break; + case QSGSoftwareRenderableNode::Painter: + m_handle.painterNode = static_cast<QSGSoftwarePainterNode*>(node); + break; + case QSGSoftwareRenderableNode::Rectangle: + m_handle.rectangleNode = static_cast<QSGSoftwareRectangleNode*>(node); + break; + case QSGSoftwareRenderableNode::Glyph: + m_handle.glpyhNode = static_cast<QSGSoftwareGlyphNode*>(node); + break; + case QSGSoftwareRenderableNode::NinePatch: + m_handle.ninePatchNode = static_cast<QSGSoftwareNinePatchNode*>(node); + break; + case QSGSoftwareRenderableNode::Invalid: + m_handle.simpleRectNode = nullptr; + break; + } +} + +QSGSoftwareRenderableNode::~QSGSoftwareRenderableNode() +{ + +} + +void QSGSoftwareRenderableNode::update() +{ + // Update the Node properties + m_isDirty = true; + + QRect boundingRect; + + switch (m_nodeType) { + case QSGSoftwareRenderableNode::SimpleRect: + if (m_handle.simpleRectNode->color().alpha() == 255 && !m_transform.isRotating()) + m_isOpaque = true; + else + m_isOpaque = false; + + boundingRect = m_handle.simpleRectNode->rect().toRect(); + break; + case QSGSoftwareRenderableNode::SimpleTexture: + if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel() && !m_transform.isRotating()) + m_isOpaque = true; + else + m_isOpaque = false; + + boundingRect = m_handle.simpleTextureNode->rect().toRect(); + break; + case QSGSoftwareRenderableNode::Image: + // There isn't a way to tell, so assume it's not + m_isOpaque = false; + + boundingRect = m_handle.imageNode->rect().toRect(); + break; + case QSGSoftwareRenderableNode::Painter: + if (m_handle.painterNode->opaquePainting() && !m_transform.isRotating()) + m_isOpaque = true; + else + m_isOpaque = false; + + boundingRect = QRect(0, 0, m_handle.painterNode->size().width(), m_handle.painterNode->size().height()); + break; + case QSGSoftwareRenderableNode::Rectangle: + if (m_handle.rectangleNode->isOpaque() && !m_transform.isRotating()) + m_isOpaque = true; + else + m_isOpaque = false; + + boundingRect = m_handle.rectangleNode->rect().toRect(); + break; + case QSGSoftwareRenderableNode::Glyph: + // Always has alpha + m_isOpaque = false; + + boundingRect = m_handle.glpyhNode->boundingRect().toAlignedRect(); + break; + case QSGSoftwareRenderableNode::NinePatch: + // Difficult to tell, assume non-opaque + m_isOpaque = false; + + boundingRect = m_handle.ninePatchNode->bounds().toRect(); + break; + default: + break; + } + + m_boundingRect = m_transform.mapRect(boundingRect); + + if (m_clipRegion.rectCount() == 1) { + m_boundingRect = m_boundingRect.intersected(m_clipRegion.rects().first()); + } + + // Overrides + if (m_opacity < 1.0f) + m_isOpaque = false; + + m_dirtyRegion = QRegion(m_boundingRect); +} + +QRegion QSGSoftwareRenderableNode::renderNode(QPainter *painter, bool forceOpaquePainting) +{ + Q_ASSERT(painter); + + // Check for don't paint conditions + if (!m_isDirty || qFuzzyIsNull(m_opacity) || m_dirtyRegion.isEmpty()) { + m_isDirty = false; + m_dirtyRegion = QRegion(); + return QRegion(); + } + + painter->save(); + painter->setOpacity(m_opacity); + + // Set clipRegion to m_dirtyRegion (in world coordinates) + // as m_dirtyRegion already accounts for clipRegion + painter->setClipRegion(m_dirtyRegion, Qt::ReplaceClip); + if (m_clipRegion.rectCount() > 1) + painter->setClipRegion(m_clipRegion, Qt::IntersectClip); + + painter->setTransform(m_transform, false); //precalculated worldTransform + if (forceOpaquePainting || m_isOpaque) + painter->setCompositionMode(QPainter::CompositionMode_Source); + + switch (m_nodeType) { + case QSGSoftwareRenderableNode::SimpleRect: + painter->fillRect(m_handle.simpleRectNode->rect(), m_handle.simpleRectNode->color()); + break; + case QSGSoftwareRenderableNode::SimpleTexture: + { + QSGTexture *texture = m_handle.simpleTextureNode->texture(); + if (QSGSoftwarePixmapTexture *pt = dynamic_cast<QSGSoftwarePixmapTexture *>(texture)) { + const QPixmap &pm = pt->pixmap(); + painter->drawPixmap(m_handle.simpleTextureNode->rect(), pm, QRectF(0, 0, pm.width(), pm.height())); + } else if (QSGPlainTexture *pt = dynamic_cast<QSGPlainTexture *>(texture)) { + const QImage &im = pt->image(); + painter->drawImage(m_handle.simpleTextureNode->rect(), im, QRectF(0, 0, im.width(), im.height())); + } + } + break; + case QSGSoftwareRenderableNode::Image: + m_handle.imageNode->paint(painter); + break; + case QSGSoftwareRenderableNode::Painter: + m_handle.painterNode->paint(painter); + break; + case QSGSoftwareRenderableNode::Rectangle: + m_handle.rectangleNode->paint(painter); + break; + case QSGSoftwareRenderableNode::Glyph: + m_handle.glpyhNode->paint(painter); + break; + case QSGSoftwareRenderableNode::NinePatch: + m_handle.ninePatchNode->paint(painter); + break; + default: + break; + } + + painter->restore(); + + QRegion areaToBeFlushed = m_dirtyRegion; + m_previousDirtyRegion = QRegion(m_boundingRect); + m_isDirty = false; + m_dirtyRegion = QRegion(); + + return areaToBeFlushed; +} + +QRect QSGSoftwareRenderableNode::boundingRect() const +{ + // This returns the bounding area of a renderable node in world coordinates + return m_boundingRect; +} + +bool QSGSoftwareRenderableNode::isDirtyRegionEmpty() const +{ + return m_dirtyRegion.isEmpty(); +} + +void QSGSoftwareRenderableNode::setTransform(const QTransform &transform) +{ + if (m_transform == transform) + return; + m_transform = transform; + update(); +} + +void QSGSoftwareRenderableNode::setClipRegion(const QRegion &clipRect) +{ + if (m_clipRegion == clipRect) + return; + + m_clipRegion = clipRect; + update(); +} + +void QSGSoftwareRenderableNode::setOpacity(float opacity) +{ + if (qFuzzyCompare(m_opacity, opacity)) + return; + + m_opacity = opacity; + update(); +} + +void QSGSoftwareRenderableNode::markGeometryDirty() +{ + update(); +} + +void QSGSoftwareRenderableNode::markMaterialDirty() +{ + update(); +} + +void QSGSoftwareRenderableNode::addDirtyRegion(const QRegion &dirtyRegion, bool forceDirty) +{ + // Check if the dirty region applys to this node + QRegion prev = m_dirtyRegion; + if (dirtyRegion.intersects(boundingRect())) { + if (forceDirty) + m_isDirty = true; + m_dirtyRegion += dirtyRegion.intersected(boundingRect()); + } + qCDebug(lcRenderable) << "addDirtyRegion: " << dirtyRegion << "old dirtyRegion: " << prev << "new dirtyRegion: " << m_dirtyRegion; +} + +void QSGSoftwareRenderableNode::subtractDirtyRegion(const QRegion &dirtyRegion) +{ + QRegion prev = m_dirtyRegion; + if (m_isDirty) { + // Check if this rect concerns us + if (dirtyRegion.intersects(QRegion(boundingRect()))) { + m_dirtyRegion -= dirtyRegion; + if (m_dirtyRegion.isEmpty()) + m_isDirty = false; + } + } + qCDebug(lcRenderable) << "subtractDirtyRegion: " << dirtyRegion << "old dirtyRegion" << prev << "new dirtyRegion: " << m_dirtyRegion; +} + +QRegion QSGSoftwareRenderableNode::previousDirtyRegion() const +{ + return m_previousDirtyRegion.subtracted(QRegion(m_boundingRect)); +} + +QRegion QSGSoftwareRenderableNode::dirtyRegion() const +{ + return m_dirtyRegion; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h new file mode 100644 index 0000000000..43ff97ed78 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARERENDERABLENODE_H +#define QSGSOFTWARERENDERABLENODE_H + +#include <QtGui/QRegion> +#include <QtCore/QRect> +#include <QtGui/QTransform> + +QT_BEGIN_NAMESPACE + +class QSGNode; +class QSGSimpleRectNode; +class QSGSimpleTextureNode; +class QSGSoftwareImageNode; +class QSGSoftwarePainterNode; +class QSGSoftwareRectangleNode; +class QSGSoftwareGlyphNode; +class QSGSoftwareNinePatchNode; + +class QSGSoftwareRenderableNode +{ +public: + enum NodeType { + Invalid = -1, + SimpleRect, + SimpleTexture, + Image, + Painter, + Rectangle, + Glyph, + NinePatch + }; + + QSGSoftwareRenderableNode(NodeType type, QSGNode *node); + ~QSGSoftwareRenderableNode(); + + void update(); + + QRegion renderNode(QPainter *painter, bool forceOpaquePainting = false); + QRect boundingRect() const; + NodeType type() const { return m_nodeType; } + bool isOpaque() const { return m_isOpaque; } + bool isDirty() const { return m_isDirty; } + bool isDirtyRegionEmpty() const; + + void setTransform(const QTransform &transform); + void setClipRegion(const QRegion &clipRegion); + void setOpacity(float opacity); + QTransform transform() const { return m_transform; } + QRegion clipRegion() const { return m_clipRegion; } + float opacity() const { return m_opacity; } + + void markGeometryDirty(); + void markMaterialDirty(); + + void addDirtyRegion(const QRegion &dirtyRegion, bool forceDirty = true); + void subtractDirtyRegion(const QRegion &dirtyRegion); + + QRegion previousDirtyRegion() const; + QRegion dirtyRegion() const; + +private: + union RenderableNodeHandle { + QSGSimpleRectNode *simpleRectNode; + QSGSimpleTextureNode *simpleTextureNode; + QSGSoftwareImageNode *imageNode; + QSGSoftwarePainterNode *painterNode; + QSGSoftwareRectangleNode *rectangleNode; + QSGSoftwareGlyphNode *glpyhNode; + QSGSoftwareNinePatchNode *ninePatchNode; + }; + + const NodeType m_nodeType; + RenderableNodeHandle m_handle; + + bool m_isOpaque; + + bool m_isDirty; + QRegion m_dirtyRegion; + QRegion m_previousDirtyRegion; + + QTransform m_transform; + QRegion m_clipRegion; + float m_opacity; + + QRect m_boundingRect; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWARERENDERABLENODE_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp new file mode 100644 index 0000000000..3d5fe21f7c --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp @@ -0,0 +1,275 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarerenderablenodeupdater_p.h" + +#include "qsgabstractsoftwarerenderer_p.h" +#include "qsgsoftwareimagenode_p.h" +#include "qsgsoftwarerectanglenode_p.h" +#include "qsgsoftwareglyphnode_p.h" +#include "qsgsoftwareninepatchnode_p.h" +#include "qsgsoftwarepainternode_p.h" +#include "qsgsoftwarepixmaptexture_p.h" + +#include <QtQuick/QSGSimpleRectNode> +#include <QtQuick/qsgsimpletexturenode.h> + +QT_BEGIN_NAMESPACE + +QSGSoftwareRenderableNodeUpdater::QSGSoftwareRenderableNodeUpdater(QSGAbstractSoftwareRenderer *renderer) + : m_renderer(renderer) +{ + m_opacityState.push(1.0f); + // Invalid RectF by default for no clip + m_clipState.push(QRegion()); + m_transformState.push(QTransform()); +} + +QSGSoftwareRenderableNodeUpdater::~QSGSoftwareRenderableNodeUpdater() +{ + +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGTransformNode *node) +{ + m_transformState.push(node->matrix().toTransform() * m_transformState.top()); + m_stateMap[node] = currentState(node); + return true; +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *) +{ + m_transformState.pop(); +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node) +{ + // Make sure to translate the clip rect into world coordinates + if (m_clipState.top().isEmpty()) { + m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect()))); + } else + m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect()).intersected(m_clipState.top()))); + m_stateMap[node] = currentState(node); + return true; +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *) +{ + m_clipState.pop(); +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGGeometryNode *node) +{ + if (QSGSimpleRectNode *rectNode = dynamic_cast<QSGSimpleRectNode *>(node)) { + return updateRenderableNode(QSGSoftwareRenderableNode::SimpleRect, rectNode); + } else if (QSGSimpleTextureNode *tn = dynamic_cast<QSGSimpleTextureNode *>(node)) { + return updateRenderableNode(QSGSoftwareRenderableNode::SimpleTexture, tn); + } else { + // We dont know, so skip + return false; + } +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGGeometryNode *) +{ +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGOpacityNode *node) +{ + m_opacityState.push(m_opacityState.top() * node->opacity()); + m_stateMap[node] = currentState(node); + return true; +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGOpacityNode *) +{ + m_opacityState.pop(); +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGImageNode *node) +{ + return updateRenderableNode(QSGSoftwareRenderableNode::Image, node); +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGImageNode *) +{ +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGPainterNode *node) +{ + return updateRenderableNode(QSGSoftwareRenderableNode::Painter, node); +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGPainterNode *) +{ +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGRectangleNode *node) +{ + return updateRenderableNode(QSGSoftwareRenderableNode::Rectangle, node); +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGRectangleNode *) +{ +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGGlyphNode *node) +{ + return updateRenderableNode(QSGSoftwareRenderableNode::Glyph, node); +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGGlyphNode *) +{ +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGNinePatchNode *node) +{ + return updateRenderableNode(QSGSoftwareRenderableNode::NinePatch, node); +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGNinePatchNode *) +{ +} + +bool QSGSoftwareRenderableNodeUpdater::visit(QSGRootNode *node) +{ + m_stateMap[node] = currentState(node); + return true; +} + +void QSGSoftwareRenderableNodeUpdater::endVisit(QSGRootNode *) +{ +} + +void QSGSoftwareRenderableNodeUpdater::updateNodes(QSGNode *node, bool isNodeRemoved) +{ + m_opacityState.clear(); + m_clipState.clear(); + m_transformState.clear(); + + auto parentNode = node->parent(); + // If the node was deleted, it will have no parent + // check if the state map has the previous parent + if ((!parentNode || isNodeRemoved ) && m_stateMap.contains(node)) + parentNode = m_stateMap[node].parent; + + // If we find a parent, use its state for updating the new children + if (parentNode && m_stateMap.contains(parentNode)) { + auto state = m_stateMap[parentNode]; + m_opacityState.push(state.opacity); + m_transformState.push(state.transform); + m_clipState.push(state.clip); + + } else { + // There is no parent, and no previous parent, so likely a root node + m_opacityState.push(1.0f); + m_transformState.push(QTransform()); + m_clipState.push(QRegion()); + } + + // If the node is being removed, then cleanup the state data + // Then just visit the children without visiting the now removed node + if (isNodeRemoved) { + m_stateMap.remove(node); + return; + } + + // Visit the current node itself first + switch (node->type()) { + case QSGNode::ClipNodeType: { + QSGClipNode *c = static_cast<QSGClipNode*>(node); + if (visit(c)) + visitChildren(c); + endVisit(c); + break; + } + case QSGNode::TransformNodeType: { + QSGTransformNode *c = static_cast<QSGTransformNode*>(node); + if (visit(c)) + visitChildren(c); + endVisit(c); + break; + } + case QSGNode::OpacityNodeType: { + QSGOpacityNode *c = static_cast<QSGOpacityNode*>(node); + if (visit(c)) + visitChildren(c); + endVisit(c); + break; + } + case QSGNode::GeometryNodeType: { + if (node->flags() & QSGNode::IsVisitableNode) { + QSGVisitableNode *v = static_cast<QSGVisitableNode*>(node); + v->accept(this); + } else { + QSGGeometryNode *c = static_cast<QSGGeometryNode*>(node); + if (visit(c)) + visitChildren(c); + endVisit(c); + } + break; + } + case QSGNode::RootNodeType: { + QSGRootNode *root = static_cast<QSGRootNode*>(node); + if (visit(root)) + visitChildren(root); + endVisit(root); + break; + } + case QSGNode::BasicNodeType: { + visitChildren(node); + break; + } + default: + Q_UNREACHABLE(); + break; + } +} + +QSGSoftwareRenderableNodeUpdater::NodeState QSGSoftwareRenderableNodeUpdater::currentState(QSGNode *node) const +{ + NodeState state; + state.opacity = m_opacityState.top(); + state.clip = m_clipState.top(); + state.transform = m_transformState.top(); + state.parent = node->parent(); + return state; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h new file mode 100644 index 0000000000..37f953d576 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARERENDERABLENODEUPDATER_H +#define QSGSOFTWARERENDERABLENODEUPDATER_H + +#include "qsgsoftwarerenderablenode_p.h" +#include "qsgabstractsoftwarerenderer_p.h" + +#include <private/qsgadaptationlayer_p.h> + +#include <QTransform> +#include <QStack> +#include <QRectF> + +QT_BEGIN_NAMESPACE + +class QSGSoftwareRenderableNodeUpdater : public QSGNodeVisitorEx +{ +public: + QSGSoftwareRenderableNodeUpdater(QSGAbstractSoftwareRenderer *renderer); + virtual ~QSGSoftwareRenderableNodeUpdater(); + + bool visit(QSGTransformNode *) override; + void endVisit(QSGTransformNode *) override; + bool visit(QSGClipNode *) override; + void endVisit(QSGClipNode *) override; + bool visit(QSGGeometryNode *) override; + void endVisit(QSGGeometryNode *) override; + bool visit(QSGOpacityNode *) override; + void endVisit(QSGOpacityNode *) override; + bool visit(QSGImageNode *) override; + void endVisit(QSGImageNode *) override; + bool visit(QSGPainterNode *) override; + void endVisit(QSGPainterNode *) override; + bool visit(QSGRectangleNode *) override; + void endVisit(QSGRectangleNode *) override; + bool visit(QSGGlyphNode *) override; + void endVisit(QSGGlyphNode *) override; + bool visit(QSGNinePatchNode *) override; + void endVisit(QSGNinePatchNode *) override; + bool visit(QSGRootNode *) override; + void endVisit(QSGRootNode *) override; + + void updateNodes(QSGNode *node, bool isNodeRemoved = false); + +private: + struct NodeState { + float opacity; + QRegion clip; + QTransform transform; + QSGNode *parent; + }; + + NodeState currentState(QSGNode *node) const; + + template<class NODE> + bool updateRenderableNode(QSGSoftwareRenderableNode::NodeType type, NODE *node); + + QSGAbstractSoftwareRenderer *m_renderer; + QStack<float> m_opacityState; + QStack<QRegion> m_clipState; + QStack<QTransform> m_transformState; + QHash<QSGNode*,NodeState> m_stateMap; +}; + +template<class NODE> +bool QSGSoftwareRenderableNodeUpdater::updateRenderableNode(QSGSoftwareRenderableNode::NodeType type, NODE *node) +{ + //Check if we already know about node + auto renderableNode = m_renderer->renderableNode(node); + if (renderableNode == nullptr) { + renderableNode = new QSGSoftwareRenderableNode(type, node); + m_renderer->addNodeMapping(node, renderableNode); + } + + //Update the node + renderableNode->setTransform(m_transformState.top()); + renderableNode->setOpacity(m_opacityState.top()); + renderableNode->setClipRegion(m_clipState.top()); + + renderableNode->update(); + m_stateMap[node] = currentState(node); + + return true; +} + +QT_END_NAMESPACE + +#endif // QSGSOFTWARERENDERABLENODEUPDATER_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp new file mode 100644 index 0000000000..939178e532 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarerenderer_p.h" + +#include "qsgsoftwarerenderablenodeupdater_p.h" +#include "qsgsoftwarerenderlistbuilder_p.h" +#include "qsgsoftwarecontext_p.h" +#include "qsgsoftwarerenderablenode_p.h" + +#include <QtGui/QWindow> +#include <QtQuick/QSGSimpleRectNode> + +#include <QElapsedTimer> + +Q_LOGGING_CATEGORY(lcRenderer, "qt.scenegraph.softwarecontext.renderer") + +QT_BEGIN_NAMESPACE + +QSGSoftwareRenderer::QSGSoftwareRenderer(QSGRenderContext *context) + : QSGAbstractSoftwareRenderer(context) +{ +} + +QSGSoftwareRenderer::~QSGSoftwareRenderer() +{ +} + +void QSGSoftwareRenderer::renderScene(uint) +{ + class B : public QSGBindable + { + public: + void bind() const { } + } bindable; + QSGRenderer::renderScene(bindable); +} + +void QSGSoftwareRenderer::render() +{ + QElapsedTimer renderTimer; + + QWindow *currentWindow = static_cast<QSGSoftwareRenderContext*>(m_context)->currentWindow; + if (!m_backingStore) + m_backingStore.reset(new QBackingStore(currentWindow)); + + if (m_backingStore->size() != currentWindow->size()) { + m_backingStore->resize(currentWindow->size()); + } + + setBackgroundColor(clearColor()); + setBackgroundSize(currentWindow->size()); + + const QRect rect(0, 0, currentWindow->width(), currentWindow->height()); + m_backingStore->beginPaint(rect); + + QPaintDevice *device = m_backingStore->paintDevice(); +#ifndef QTQUICK2D_DEBUG_FLUSH + QPainter painter(device); +#else + if (m_outputBuffer.size() != m_backingStore->size()) { + m_outputBuffer = QImage(m_backingStore->size(), QImage::Format_ARGB32_Premultiplied); + m_outputBuffer.fill(Qt::transparent); + } + QPainter painter(&m_outputBuffer); +#endif + painter.setRenderHint(QPainter::Antialiasing); + + // Build Renderlist + // The renderlist is created by visiting each node in the tree and when a + // renderable node is reach, we find the coorosponding RenderableNode object + // and append it to the renderlist. At this point the RenderableNode object + // should not need any further updating so it is just a matter of appending + // RenderableNodes + renderTimer.start(); + buildRenderList(); + qint64 buildRenderListTime = renderTimer.restart(); + + // Optimize Renderlist + // This is a pass through the renderlist to determine what actually needs to + // be painted. Without this pass the renderlist will simply render each item + // from back to front, with a high potential for overdraw. It would also lead + // to the entire window being flushed every frame. The objective of the + // optimization pass is to only paint dirty nodes that are not occuluded. A + // side effect of this is that additional nodes may need to be marked dirty to + // force a repaint. It is also important that any item that needs to be + // repainted only paints what is needed, via the use of clip regions. + optimizeRenderList(); + qint64 optimizeRenderListTime = renderTimer.restart(); + + // Render the contents Renderlist + QRegion dirtyRegion = renderNodes(&painter); + qint64 renderTime = renderTimer.elapsed(); + + qCDebug(lcRenderer) << "render" << dirtyRegion << buildRenderListTime << optimizeRenderListTime << renderTime; + +#ifdef QTQUICK2D_DEBUG_FLUSH + // Keep up with the last 5 flushes + if (m_previousFlushes.count() == 5) + m_previousFlushes.pop_front(); + m_previousFlushes.append(dirtyRegion); + + QPainter backingStorePainter(device); + backingStorePainter.drawImage(QRect(0, 0, m_backingStore->size().width(), m_backingStore->size().height()), m_outputBuffer, m_outputBuffer.rect()); + QPen pen(Qt::NoPen); + QBrush brush(QColor(255, 0, 0, 50)); + backingStorePainter.setPen(pen); + backingStorePainter.setBrush(brush); + for (auto region : qAsConst(m_previousFlushes)) { + backingStorePainter.drawRects(region.rects()); + } + m_backingStore->endPaint(); + + m_backingStore->flush(rect); +#else + m_backingStore->endPaint(); + // Flush the updated regions to the window + m_backingStore->flush(dirtyRegion); +#endif +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h new file mode 100644 index 0000000000..daa5e2cd7c --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARERENDERER_H +#define QSGSOFTWARERENDERER_H + +#include "qsgabstractsoftwarerenderer_p.h" + +#include <QtGui/QBackingStore> + +#ifdef QTQUICK2D_DEBUG_FLUSH +#include <QtGui/QImage> +#endif + +QT_BEGIN_NAMESPACE + +class QSGSimpleRectNode; + +class QSGSoftwareRenderer : public QSGAbstractSoftwareRenderer +{ +public: + QSGSoftwareRenderer(QSGRenderContext *context); + virtual ~QSGSoftwareRenderer(); + + QBackingStore *backingStore() const { return m_backingStore.data(); } + +protected: + void renderScene(uint fboId = 0) final; + void render() final; + +private: + QScopedPointer<QBackingStore> m_backingStore; + +#ifdef QTQUICK2D_DEBUG_FLUSH + QVector<QRegion> m_previousFlushes; + QImage m_outputBuffer; +#endif +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWARERENDERER_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder.cpp new file mode 100644 index 0000000000..af81ff61c3 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarerenderlistbuilder_p.h" + +#include "qsgsoftwarerenderablenode_p.h" +#include "qsgabstractsoftwarerenderer_p.h" +#include "qsgsoftwareimagenode_p.h" +#include "qsgsoftwarerectanglenode_p.h" +#include "qsgsoftwareglyphnode_p.h" +#include "qsgsoftwareninepatchnode_p.h" +#include "qsgsoftwarepainternode_p.h" +#include "qsgsoftwarepixmaptexture_p.h" + +#include <QtQuick/QSGSimpleRectNode> +#include <QtQuick/qsgsimpletexturenode.h> + +QT_BEGIN_NAMESPACE + +QSGSoftwareRenderListBuilder::QSGSoftwareRenderListBuilder(QSGAbstractSoftwareRenderer *renderer) + : m_renderer(renderer) +{ + +} + +bool QSGSoftwareRenderListBuilder::visit(QSGTransformNode *) +{ + return true; +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGTransformNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGClipNode *) +{ + return true; +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGClipNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGGeometryNode *node) +{ + return addRenderableNode(node); +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGGeometryNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGOpacityNode *) +{ + return true; +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGOpacityNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGImageNode *node) +{ + return addRenderableNode(node); +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGImageNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGPainterNode *node) +{ + return addRenderableNode(node); +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGPainterNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGRectangleNode *node) +{ + return addRenderableNode(node); +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGRectangleNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGGlyphNode *node) +{ + return addRenderableNode(node); +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGGlyphNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGNinePatchNode *node) +{ + return addRenderableNode(node); +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGNinePatchNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::visit(QSGRootNode *) +{ + return true; +} + +void QSGSoftwareRenderListBuilder::endVisit(QSGRootNode *) +{ +} + +bool QSGSoftwareRenderListBuilder::addRenderableNode(QSGNode *node) +{ + auto renderableNode = m_renderer->renderableNode(node); + if (renderableNode == nullptr) { + // Not a node we can render + return false; + } + m_renderer->appendRenderableNode(renderableNode); + return true; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder_p.h new file mode 100644 index 0000000000..d0d492c368 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARERENDERLISTBUILDER_H +#define QSGSOFTWARERENDERLISTBUILDER_H + +#include <private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +class QSGAbstractSoftwareRenderer; + +class QSGSoftwareRenderListBuilder : public QSGNodeVisitorEx +{ +public: + QSGSoftwareRenderListBuilder(QSGAbstractSoftwareRenderer *renderer); + + bool visit(QSGTransformNode *) override; + void endVisit(QSGTransformNode *) override; + bool visit(QSGClipNode *) override; + void endVisit(QSGClipNode *) override; + bool visit(QSGGeometryNode *) override; + void endVisit(QSGGeometryNode *) override; + bool visit(QSGOpacityNode *) override; + void endVisit(QSGOpacityNode *) override; + bool visit(QSGImageNode *) override; + void endVisit(QSGImageNode *) override; + bool visit(QSGPainterNode *) override; + void endVisit(QSGPainterNode *) override; + bool visit(QSGRectangleNode *) override; + void endVisit(QSGRectangleNode *) override; + bool visit(QSGGlyphNode *) override; + void endVisit(QSGGlyphNode *) override; + bool visit(QSGNinePatchNode *) override; + void endVisit(QSGNinePatchNode *) override; + bool visit(QSGRootNode *) override; + void endVisit(QSGRootNode *) override; + +private: + bool addRenderableNode(QSGNode *node); + + QSGAbstractSoftwareRenderer *m_renderer; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWARERENDERLISTBUILDER_H diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp new file mode 100644 index 0000000000..d004aa70d8 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsoftwarerenderloop_p.h" + +#include "qsgsoftwarecontext_p.h" + +#include <QtCore/QCoreApplication> + +#include <private/qquickwindow_p.h> +#include <QElapsedTimer> +#include <private/qquickprofiler_p.h> +#include <private/qsgsoftwarerenderer_p.h> +#include <qpa/qplatformbackingstore.h> + +QT_BEGIN_NAMESPACE + +QSGSoftwareRenderLoop::QSGSoftwareRenderLoop() +{ + sg = QSGContext::createDefaultContext(); + rc = sg->createRenderContext(); +} + +QSGSoftwareRenderLoop::~QSGSoftwareRenderLoop() +{ + delete rc; + delete sg; +} + +void QSGSoftwareRenderLoop::show(QQuickWindow *window) +{ + WindowData data; + data.updatePending = false; + data.grabOnly = false; + m_windows[window] = data; + + maybeUpdate(window); +} + +void QSGSoftwareRenderLoop::hide(QQuickWindow *window) +{ + QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window); + cd->fireAboutToStop(); +} + +void QSGSoftwareRenderLoop::windowDestroyed(QQuickWindow *window) +{ + m_windows.remove(window); + hide(window); + + QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); + d->cleanupNodesOnShutdown(); + + if (m_windows.size() == 0) { + rc->invalidate(); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + } +} + +void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window) +{ + QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window); + if (!cd->isRenderable() || !m_windows.contains(window)) + return; + + WindowData &data = const_cast<WindowData &>(m_windows[window]); + + // ### create QPainter and set up pointer to current window/painter + QSGSoftwareRenderContext *ctx = static_cast<QSGSoftwareRenderContext*>(cd->context); + ctx->currentWindow = window; + ctx->initializeIfNeeded(); + + bool alsoSwap = data.updatePending; + data.updatePending = false; + + if (!data.grabOnly) { + cd->flushDelayedTouchEvent(); + // Event delivery/processing triggered the window to be deleted or stop rendering. + if (!m_windows.contains(window)) + return; + } + QElapsedTimer renderTimer; + qint64 renderTime = 0, syncTime = 0, polishTime = 0; + bool profileFrames = QSG_RASTER_LOG_TIME_RENDERLOOP().isDebugEnabled(); + if (profileFrames) + renderTimer.start(); + Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame); + + cd->polishItems(); + + if (profileFrames) + polishTime = renderTimer.nsecsElapsed(); + Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame, + QQuickProfiler::SceneGraphRenderLoopFrame); + + emit window->afterAnimating(); + + cd->syncSceneGraph(); + + if (profileFrames) + syncTime = renderTimer.nsecsElapsed(); + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); + + cd->renderSceneGraph(window->size()); + + if (profileFrames) + renderTime = renderTimer.nsecsElapsed(); + Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame); + + if (data.grabOnly) { + grabContent = static_cast<QSGSoftwareRenderer*>(cd->renderer)->backingStore()->handle()->toImage(); + data.grabOnly = false; + } + + if (alsoSwap && window->isVisible()) { + cd->fireFrameSwapped(); + } + + qint64 swapTime = 0; + if (profileFrames) + swapTime = renderTimer.nsecsElapsed(); + Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame); + + if (QSG_RASTER_LOG_TIME_RENDERLOOP().isDebugEnabled()) { + static QTime lastFrameTime = QTime::currentTime(); + qCDebug(QSG_RASTER_LOG_TIME_RENDERLOOP, + "Frame rendered with 'basic' renderloop in %dms, polish=%d, sync=%d, render=%d, swap=%d, frameDelta=%d", + int(swapTime / 1000000), + int(polishTime / 1000000), + int((syncTime - polishTime) / 1000000), + int((renderTime - syncTime) / 1000000), + int((swapTime - renderTime) / 10000000), + int(lastFrameTime.msecsTo(QTime::currentTime()))); + lastFrameTime = QTime::currentTime(); + } + + // Might have been set during syncSceneGraph() + if (data.updatePending) + maybeUpdate(window); +} + +void QSGSoftwareRenderLoop::exposureChanged(QQuickWindow *window) +{ + if (window->isExposed()) { + m_windows[window].updatePending = true; + renderWindow(window); + } +} + +QImage QSGSoftwareRenderLoop::grab(QQuickWindow *window) +{ + if (!m_windows.contains(window)) + return QImage(); + + m_windows[window].grabOnly = true; + + renderWindow(window); + + QImage grabbed = grabContent; + grabContent = QImage(); + return grabbed; +} + + + +void QSGSoftwareRenderLoop::maybeUpdate(QQuickWindow *window) +{ + if (!m_windows.contains(window)) + return; + + m_windows[window].updatePending = true; + window->requestUpdate(); +} + +QSurface::SurfaceType QSGSoftwareRenderLoop::windowSurfaceType() const +{ + return QSurface::RasterSurface; +} + + + +QSGContext *QSGSoftwareRenderLoop::sceneGraphContext() const +{ + return sg; +} + + +void QSGSoftwareRenderLoop::handleUpdateRequest(QQuickWindow *window) +{ + renderWindow(window); +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h new file mode 100644 index 0000000000..ed69f86eff --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSOFTWARERENDERLOOP_H +#define QSGSOFTWARERENDERLOOP_H + +#include <private/qsgrenderloop_p.h> + +QT_BEGIN_NAMESPACE + +class QSGSoftwareRenderLoop : public QSGRenderLoop +{ + Q_OBJECT +public: + QSGSoftwareRenderLoop(); + ~QSGSoftwareRenderLoop(); + + void show(QQuickWindow *window) override; + void hide(QQuickWindow *window) override; + + void windowDestroyed(QQuickWindow *window) override; + + void renderWindow(QQuickWindow *window); + void exposureChanged(QQuickWindow *window) override; + QImage grab(QQuickWindow *window) override; + + void maybeUpdate(QQuickWindow *window) override; + void update(QQuickWindow *window) override { maybeUpdate(window); } // identical for this implementation. + void handleUpdateRequest(QQuickWindow *) override; + + void releaseResources(QQuickWindow *) override { } + + QSurface::SurfaceType windowSurfaceType() const override; + + QAnimationDriver *animationDriver() const override { return 0; } + + QSGContext *sceneGraphContext() const override; + QSGRenderContext *createRenderContext(QSGContext *) const override { return rc; } + + struct WindowData { + bool updatePending : 1; + bool grabOnly : 1; + }; + + QHash<QQuickWindow *, WindowData> m_windows; + + QSGContext *sg; + QSGRenderContext *rc; + + QImage grabContent; +}; + +QT_END_NAMESPACE + +#endif // QSGSOFTWARERENDERLOOP_H diff --git a/src/quick/scenegraph/adaptations/software/software.pri b/src/quick/scenegraph/adaptations/software/software.pri new file mode 100644 index 0000000000..b8cdbc4a25 --- /dev/null +++ b/src/quick/scenegraph/adaptations/software/software.pri @@ -0,0 +1,39 @@ +QT += gui-private core-private qml-private + +#DEFINES += QTQUICK2D_DEBUG_FLUSH + +SOURCES += \ + $$PWD/qsgsoftwarecontext.cpp \ + $$PWD/qsgabstractsoftwarerenderer.cpp \ + $$PWD/qsgsoftwareglyphnode.cpp \ + $$PWD/qsgsoftwareimagenode.cpp \ + $$PWD/qsgsoftwareninepatchnode.cpp \ + $$PWD/qsgsoftwarepainternode.cpp \ + $$PWD/qsgsoftwarerectanglenode.cpp \ + $$PWD/qsgsoftwarepixmaprenderer.cpp \ + $$PWD/qsgsoftwarepixmaptexture.cpp \ + $$PWD/qsgsoftwarerenderablenode.cpp \ + $$PWD/qsgsoftwarerenderablenodeupdater.cpp \ + $$PWD/qsgsoftwarerenderer.cpp \ + $$PWD/qsgsoftwarerenderlistbuilder.cpp \ + $$PWD/qsgsoftwarerenderloop.cpp \ + $$PWD/qsgsoftwarelayer.cpp \ + $$PWD/qsgsoftwareadaptation.cpp + +HEADERS += \ + $$PWD/qsgsoftwarecontext_p.h \ + $$PWD/qsgabstractsoftwarerenderer_p.h \ + $$PWD/qsgsoftwareglyphnode_p.h \ + $$PWD/qsgsoftwareimagenode_p.h \ + $$PWD/qsgsoftwareninepatchnode_p.h \ + $$PWD/qsgsoftwarepainternode_p.h \ + $$PWD/qsgsoftwarepixmaprenderer_p.h \ + $$PWD/qsgsoftwarepixmaptexture_p.h \ + $$PWD/qsgsoftwarerectanglenode_p.h \ + $$PWD/qsgsoftwarerenderablenode_p.h \ + $$PWD/qsgsoftwarerenderablenodeupdater_p.h \ + $$PWD/qsgsoftwarerenderer_p.h \ + $$PWD/qsgsoftwarerenderlistbuilder_p.h \ + $$PWD/qsgsoftwarerenderloop_p.h \ + $$PWD/qsgsoftwarelayer_p.h \ + $$PWD/qsgsoftwareadaptation_p.h diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h index d0a22c8c10..eb9e7cea7c 100644 --- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h +++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h @@ -42,6 +42,10 @@ #include <QtQuick/qsgnode.h> +#ifndef GLuint +#define GLuint uint +#endif + QT_BEGIN_NAMESPACE class QSGAbstractRendererPrivate; diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index e657307efd..a89dbc0ea2 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -154,8 +154,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) p->bindAttributeLocation(attr[i], i); } p->bindAttributeLocation("_qt_order", i); - context->compile(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), 0); - context->initialize(s); + context->compileShader(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), 0); + context->initializeShader(s); if (!p->isLinked()) return 0; @@ -188,8 +188,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame); QSGMaterialShader *s = static_cast<QSGMaterialShader *>(material->createShader()); - context->compile(s, material); - context->initialize(s); + context->compileShader(s, material); + context->initializeShader(s); shader = new Shader(); shader->program = s; @@ -751,8 +751,9 @@ static int qsg_countNodesInBatches(const QDataBuffer<Batch *> &batches) return sum; } -Renderer::Renderer(QSGRenderContext *ctx) +Renderer::Renderer(QSGDefaultRenderContext *ctx) : QSGRenderer(ctx) + , m_context(ctx) , m_opaqueRenderList(64) , m_alphaRenderList(64) , m_nextRenderOrder(0) @@ -812,7 +813,7 @@ Renderer::Renderer(QSGRenderContext *ctx) // If rendering with an OpenGL Core profile context, we need to create a VAO // to hold our vertex specification state. - if (context()->openglContext()->format().profile() == QSurfaceFormat::CoreProfile) { + if (m_context->openglContext()->format().profile() == QSurfaceFormat::CoreProfile) { m_vao = new QOpenGLVertexArrayObject(this); m_vao->create(); } @@ -1106,7 +1107,7 @@ void Renderer::nodeWasRemoved(Node *node) if (m_renderNodeElements.isEmpty()) { static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); - m_useDepthBuffer = useDepth && context()->openglContext()->format().depthBufferSize() > 0; + m_useDepthBuffer = useDepth && m_context->openglContext()->format().depthBufferSize() > 0; } } } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 5dbbc22870..a84ac6d177 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -54,6 +54,7 @@ // #include <private/qsgrenderer_p.h> +#include <private/qsgdefaultrendercontext_p.h> #include <private/qsgnodeupdater_p.h> #include <private/qdatabuffer_p.h> @@ -61,6 +62,8 @@ #include <QtCore/QBitArray> +#include <QtGui/QOpenGLFunctions> + QT_BEGIN_NAMESPACE class QOpenGLVertexArrayObject; @@ -527,7 +530,7 @@ public: float lastOpacity; }; - ShaderManager(QSGRenderContext *ctx) : blitProgram(0), visualizeProgram(0), context(ctx) { } + ShaderManager(QSGDefaultRenderContext *ctx) : blitProgram(0), visualizeProgram(0), context(ctx) { } ~ShaderManager() { qDeleteAll(rewrittenShaders); qDeleteAll(stockShaders); @@ -545,13 +548,13 @@ public: QOpenGLShaderProgram *blitProgram; QOpenGLShaderProgram *visualizeProgram; - QSGRenderContext *context; + QSGDefaultRenderContext *context; }; class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer, public QOpenGLFunctions { public: - Renderer(QSGRenderContext *); + Renderer(QSGDefaultRenderContext *); ~Renderer(); enum VisualizeMode { @@ -635,6 +638,7 @@ private: void visualizeDrawGeometry(const QSGGeometry *g); void setCustomRenderMode(const QByteArray &mode) Q_DECL_OVERRIDE; + QSGDefaultRenderContext *m_context; QSet<Node *> m_taggedRoots; QDataBuffer<Element *> m_opaqueRenderList; QDataBuffer<Element *> m_alphaRenderList; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp index 5012f6a31b..64635edc4f 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.cpp +++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp @@ -39,10 +39,11 @@ #include "qsggeometry.h" #include "qsggeometry_p.h" - -#include <qopenglcontext.h> -#include <qopenglfunctions.h> -#include <private/qopenglextensions_p.h> +#ifndef QT_NO_OPENGL +# include <qopenglcontext.h> +# include <qopenglfunctions.h> +# include <private/qopenglextensions_p.h> +#endif #ifdef Q_OS_QNX #include <malloc.h> @@ -53,10 +54,21 @@ QT_BEGIN_NAMESPACE QSGGeometry::Attribute QSGGeometry::Attribute::create(int attributeIndex, int tupleSize, int primitiveType, bool isPrimitive) { - Attribute a = { attributeIndex, tupleSize, primitiveType, isPrimitive, 0 }; + Attribute a = { attributeIndex, tupleSize, primitiveType, isPrimitive, UNKNOWN, 0 }; return a; } +QSGGeometry::Attribute QSGGeometry::Attribute::createWithSemantic(int pos, int tupleSize, int type, Semantic semantic) +{ + Attribute a; + a.position = pos; + a.tupleSize = tupleSize; + a.type = type; + a.isVertexCoordinate = semantic == POSITION; + a.semantic = semantic; + a.reserved = 0; + return a; +} /*! Convenience function which returns attributes to be used for 2D solid @@ -66,7 +78,7 @@ QSGGeometry::Attribute QSGGeometry::Attribute::create(int attributeIndex, int tu const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D() { static Attribute data[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true) + Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION) }; static AttributeSet attrs = { 1, sizeof(float) * 2, data }; return attrs; @@ -79,8 +91,8 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D() const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D() { static Attribute data[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), - QSGGeometry::Attribute::create(1, 2, GL_FLOAT) + Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION), + Attribute::createWithSemantic(1, 2, TypeFloat, Attribute::TEXCOORD) }; static AttributeSet attrs = { 2, sizeof(float) * 4, data }; return attrs; @@ -93,8 +105,8 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D( const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() { static Attribute data[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), - QSGGeometry::Attribute::create(1, 4, GL_UNSIGNED_BYTE) + Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION), + Attribute::createWithSemantic(1, 4, TypeUnsignedByte, Attribute::COLOR) }; static AttributeSet attrs = { 2, 2 * sizeof(float) + 4 * sizeof(char), data }; return attrs; @@ -394,7 +406,7 @@ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, int vertexCount, int indexCount, int indexType) - : m_drawing_mode(GL_TRIANGLE_STRIP) + : m_drawing_mode(DrawTriangleStrip) , m_vertex_count(0) , m_index_count(0) , m_index_type(indexType) @@ -410,21 +422,20 @@ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, Q_UNUSED(m_reserved_bits); Q_ASSERT(m_attributes.count > 0); Q_ASSERT(m_attributes.stride > 0); - +#ifndef QT_NO_OPENGL Q_ASSERT_X(indexType != GL_UNSIGNED_INT || static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions()) ->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint), "QSGGeometry::QSGGeometry", "GL_UNSIGNED_INT is not supported, geometry will not render" ); - - if (indexType != GL_UNSIGNED_BYTE - && indexType != GL_UNSIGNED_SHORT - && indexType != GL_UNSIGNED_INT) { +#endif + if (indexType != TypeUnsignedByte + && indexType != TypeUnsignedShort + && indexType != TypeUnsignedInt) { qFatal("QSGGeometry: Unsupported index type, %x.\n", indexType); } - // Because allocate reads m_vertex_count, m_index_count and m_owns_data, these // need to be set before calling allocate... allocate(vertexCount, indexCount); @@ -520,11 +531,17 @@ const void *QSGGeometry::indexData() const The default value is \c GL_TRIANGLE_STRIP. */ +#ifndef QT_NO_OPENGL void QSGGeometry::setDrawingMode(GLenum mode) { m_drawing_mode = mode; } - +#else +void QSGGeometry::setDrawingMode(int mode) +{ + m_drawing_mode = mode; +} +#endif /*! Gets the current line or point width or to be used for this geometry. This property only applies to line width when the drawingMode is \c GL_LINES, \c GL_LINE_STRIP, or @@ -601,8 +618,8 @@ void QSGGeometry::allocate(int vertexCount, int indexCount) m_index_data_offset = -1; m_owns_data = false; } else { - Q_ASSERT(m_index_type == GL_UNSIGNED_INT || m_index_type == GL_UNSIGNED_SHORT); - int indexByteSize = indexCount * (m_index_type == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32)); + Q_ASSERT(m_index_type == TypeUnsignedInt || m_index_type == TypeUnsignedShort); + int indexByteSize = indexCount * (m_index_type == TypeUnsignedShort ? sizeof(quint16) : sizeof(quint32)); m_data = (void *) malloc(vertexByteSize + indexByteSize); m_index_data_offset = vertexByteSize; m_owns_data = true; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h index 5773b6abd1..8d0cd03968 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.h +++ b/src/quick/scenegraph/coreapi/qsggeometry.h @@ -54,15 +54,27 @@ public: struct Q_QUICK_EXPORT Attribute { + enum Semantic { + UNKNOWN, + POSITION, + COLOR, + TEXCOORD, + TEXCOORD1, + TEXCOORD2 + }; + int position; int tupleSize; int type; uint isVertexCoordinate : 1; - uint reserved : 31; + Semantic semantic : 4; + + uint reserved : 27; static Attribute create(int pos, int tupleSize, int primitiveType, bool isPosition = false); + static Attribute createWithSemantic(int pos, int tupleSize, int type, Semantic semantic); }; struct AttributeSet { @@ -104,14 +116,42 @@ public: StaticPattern = 3 }; + // Equivalents to GL_* drawing modes. + enum DrawingMode { + DrawPoints = 0x0000, + DrawLines = 0x0001, + DrawLineLoop = 0x0002, + DrawLineStrip = 0x0003, + DrawTriangles = 0x0004, + DrawTriangleStrip = 0x0005, + DrawTriangleFan = 0x0006 + }; + + // Equivalents to GL_BYTE and similar type constants. + enum Type { + TypeByte = 0x1400, + TypeUnsignedByte = 0x1401, + TypeShort = 0x1402, + TypeUnsignedShort = 0x1403, + TypeInt = 0x1404, + TypeUnsignedInt = 0x1405, + TypeFloat = 0x1406 + }; + QSGGeometry(const QSGGeometry::AttributeSet &attribs, int vertexCount, int indexCount = 0, - int indexType = GL_UNSIGNED_SHORT); + int indexType = TypeUnsignedShort); virtual ~QSGGeometry(); +#ifndef QT_NO_OPENGL + // ### Qt 6: GL types to be removed from the public API void setDrawingMode(GLenum mode); inline GLenum drawingMode() const { return m_drawing_mode; } +#else + void setDrawingMode(int mode); + inline int drawingMode() const { return m_drawing_mode; } +#endif void allocate(int vertexCount, int indexCount = 0); @@ -187,25 +227,25 @@ private: inline uint *QSGGeometry::indexDataAsUInt() { - Q_ASSERT(m_index_type == GL_UNSIGNED_INT); + Q_ASSERT(m_index_type == TypeUnsignedInt); return static_cast<uint *>(indexData()); } inline quint16 *QSGGeometry::indexDataAsUShort() { - Q_ASSERT(m_index_type == GL_UNSIGNED_SHORT); + Q_ASSERT(m_index_type == TypeUnsignedShort); return static_cast<quint16 *>(indexData()); } inline const uint *QSGGeometry::indexDataAsUInt() const { - Q_ASSERT(m_index_type == GL_UNSIGNED_INT); + Q_ASSERT(m_index_type == TypeUnsignedInt); return static_cast<const uint *>(indexData()); } inline const quint16 *QSGGeometry::indexDataAsUShort() const { - Q_ASSERT(m_index_type == GL_UNSIGNED_SHORT); + Q_ASSERT(m_index_type == TypeUnsignedShort); return static_cast<const quint16 *>(indexData()); } @@ -214,7 +254,7 @@ inline QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() Q_ASSERT(m_attributes.count == 1); Q_ASSERT(m_attributes.stride == 2 * sizeof(float)); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); + Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); Q_ASSERT(m_attributes.attributes[0].position == 0); return static_cast<Point2D *>(m_data); } @@ -225,10 +265,10 @@ inline QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoint2D() Q_ASSERT(m_attributes.stride == 4 * sizeof(float)); Q_ASSERT(m_attributes.attributes[0].position == 0); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); + Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); Q_ASSERT(m_attributes.attributes[1].position == 1); Q_ASSERT(m_attributes.attributes[1].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[1].type == GL_FLOAT); + Q_ASSERT(m_attributes.attributes[1].type == TypeFloat); return static_cast<TexturedPoint2D *>(m_data); } @@ -238,10 +278,10 @@ inline QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2D() Q_ASSERT(m_attributes.stride == 2 * sizeof(float) + 4 * sizeof(char)); Q_ASSERT(m_attributes.attributes[0].position == 0); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); + Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); Q_ASSERT(m_attributes.attributes[1].position == 1); Q_ASSERT(m_attributes.attributes[1].tupleSize == 4); - Q_ASSERT(m_attributes.attributes[1].type == GL_UNSIGNED_BYTE); + Q_ASSERT(m_attributes.attributes[1].type == TypeUnsignedByte); return static_cast<ColoredPoint2D *>(m_data); } @@ -250,7 +290,7 @@ inline const QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() const Q_ASSERT(m_attributes.count == 1); Q_ASSERT(m_attributes.stride == 2 * sizeof(float)); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); + Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); Q_ASSERT(m_attributes.attributes[0].position == 0); return static_cast<const Point2D *>(m_data); } @@ -261,10 +301,10 @@ inline const QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoin Q_ASSERT(m_attributes.stride == 4 * sizeof(float)); Q_ASSERT(m_attributes.attributes[0].position == 0); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); + Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); Q_ASSERT(m_attributes.attributes[1].position == 1); Q_ASSERT(m_attributes.attributes[1].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[1].type == GL_FLOAT); + Q_ASSERT(m_attributes.attributes[1].type == TypeFloat); return static_cast<const TexturedPoint2D *>(m_data); } @@ -274,18 +314,18 @@ inline const QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2 Q_ASSERT(m_attributes.stride == 2 * sizeof(float) + 4 * sizeof(char)); Q_ASSERT(m_attributes.attributes[0].position == 0); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == GL_FLOAT); + Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); Q_ASSERT(m_attributes.attributes[1].position == 1); Q_ASSERT(m_attributes.attributes[1].tupleSize == 4); - Q_ASSERT(m_attributes.attributes[1].type == GL_UNSIGNED_BYTE); + Q_ASSERT(m_attributes.attributes[1].type == TypeUnsignedByte); return static_cast<const ColoredPoint2D *>(m_data); } int QSGGeometry::sizeOfIndex() const { - if (m_index_type == GL_UNSIGNED_SHORT) return 2; - else if (m_index_type == GL_UNSIGNED_BYTE) return 1; - else if (m_index_type == GL_UNSIGNED_INT) return 4; + if (m_index_type == TypeUnsignedShort) return 2; + else if (m_index_type == TypeUnsignedByte) return 1; + else if (m_index_type == TypeUnsignedInt) return 4; return 0; } diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index ceb53d0d14..42a4c4abd3 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -40,7 +40,13 @@ #include "qsgmaterial.h" #include "qsgrenderer_p.h" #include "qsgmaterialshader_p.h" -#include <private/qsgshadersourcebuilder_p.h> +#ifndef QT_NO_OPENGL +# include <private/qsgshadersourcebuilder_p.h> +# include <private/qsgdefaultcontext_p.h> +# include <private/qsgdefaultrendercontext_p.h> +# include <QtGui/QOpenGLFunctions> +# include <QtGui/QOpenGLContext> +#endif QT_BEGIN_NAMESPACE @@ -58,7 +64,7 @@ void qsg_set_material_failure() qsg_material_failure = true; } #endif - +#ifndef QT_NO_OPENGL const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType type) const { QStringList files = m_sourceFiles[type]; @@ -68,6 +74,7 @@ const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType m_sources[type] = builder.source(); return m_sources[type].constData(); } +#endif #ifndef QT_NO_DEBUG static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK"); @@ -220,7 +227,7 @@ QSGMaterialShader::~QSGMaterialShader() defines the attribute register position in the vertex shader. */ - +#ifndef QT_NO_OPENGL /*! \fn const char *QSGMaterialShader::vertexShader() const @@ -256,7 +263,7 @@ const char *QSGMaterialShader::fragmentShader() const Returns the shader program used by this QSGMaterialShader. */ - +#endif /*! \fn void QSGMaterialShader::initialize() @@ -313,6 +320,7 @@ void QSGMaterialShader::updateState(const RenderState & /* state */, QSGMaterial { } +#ifndef QT_NO_OPENGL /*! Sets the GLSL source file for the shader stage \a type to \a sourceFile. The default implementation of the vertexShader() and fragmentShader() functions @@ -388,7 +396,7 @@ void QSGMaterialShader::compile() } } - +#endif /*! \class QSGMaterialShader::RenderState @@ -542,7 +550,7 @@ QRect QSGMaterialShader::RenderState::deviceRect() const return static_cast<const QSGRenderer *>(m_data)->deviceRect(); } - +#ifndef QT_NO_OPENGL /*! Returns the QOpenGLContext that is being used for rendering @@ -550,9 +558,15 @@ QRect QSGMaterialShader::RenderState::deviceRect() const QOpenGLContext *QSGMaterialShader::RenderState::context() const { - return static_cast<const QSGRenderer *>(m_data)->context()->openglContext(); + // Only the QSGDefaultRenderContext will have an OpenGL Context to query + auto openGLRenderContext = static_cast<const QSGDefaultRenderContext *>(static_cast<const QSGRenderer *>(m_data)->context()); + if (openGLRenderContext != nullptr) + return openGLRenderContext->openglContext(); + else + return nullptr; } +#endif #ifndef QT_NO_DEBUG static int qt_material_count = 0; diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.h b/src/quick/scenegraph/coreapi/qsgmaterial.h index 0a6a340092..13d15a089e 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.h +++ b/src/quick/scenegraph/coreapi/qsgmaterial.h @@ -41,7 +41,11 @@ #define QSGMATERIAL_H #include <QtQuick/qtquickglobal.h> -#include <QtGui/qopenglshaderprogram.h> +#ifndef QT_NO_OPENGL +# include <QtGui/qopenglshaderprogram.h> +#endif +#include <QtGui/QMatrix4x4> +#include <QtCore/QRect> QT_BEGIN_NAMESPACE @@ -77,9 +81,9 @@ public: QRect deviceRect() const; float determinant() const; float devicePixelRatio() const; - +#ifndef QT_NO_OPENGL QOpenGLContext *context() const; - +#endif private: friend class QSGRenderer; DirtyStates m_dirty; @@ -94,27 +98,30 @@ public: // First time a material is used, oldMaterial is null. virtual void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial); virtual char const *const *attributeNames() const = 0; // Array must end with null. - +#ifndef QT_NO_OPENGL inline QOpenGLShaderProgram *program() { return &m_program; } - +#endif protected: Q_DECLARE_PRIVATE(QSGMaterialShader) QSGMaterialShader(QSGMaterialShaderPrivate &dd); - friend class QSGRenderContext; + friend class QSGDefaultRenderContext; friend class QSGBatchRenderer::ShaderManager; - +#ifndef QT_NO_OPENGL void setShaderSourceFile(QOpenGLShader::ShaderType type, const QString &sourceFile); void setShaderSourceFiles(QOpenGLShader::ShaderType type, const QStringList &sourceFiles); virtual void compile(); +#endif virtual void initialize() { } - +#ifndef QT_NO_OPENGL virtual const char *vertexShader() const; virtual const char *fragmentShader() const; - +#endif private: +#ifndef QT_NO_OPENGL QOpenGLShaderProgram m_program; +#endif QScopedPointer<QSGMaterialShaderPrivate> d_ptr; }; diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h index 291c0cc57c..0dbce010db 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h +++ b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h @@ -59,10 +59,12 @@ QT_BEGIN_NAMESPACE class Q_QUICK_PRIVATE_EXPORT QSGMaterialShaderPrivate { public: +#ifndef QT_NO_OPENGL const char *loadShaderSource(QOpenGLShader::ShaderType type) const; QHash<QOpenGLShader::ShaderType, QStringList> m_sourceFiles; mutable QHash<QOpenGLShader::ShaderType, QByteArray> m_sources; +#endif }; #ifndef QT_NO_DEBUG diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index 223c555f3e..02c0414bc4 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -1472,15 +1472,15 @@ QDebug operator<<(QDebug d, const QSGGeometryNode *n) } else { switch (g->drawingMode()) { - case GL_TRIANGLE_STRIP: d << "strip"; break; - case GL_TRIANGLE_FAN: d << "fan"; break; - case GL_TRIANGLES: d << "triangles"; break; + case QSGGeometry::DrawTriangleStrip: d << "strip"; break; + case QSGGeometry::DrawTriangleFan: d << "fan"; break; + case QSGGeometry::DrawTriangles: d << "triangles"; break; default: break; } d << "#V:" << g->vertexCount() << "#I:" << g->indexCount(); - if (g->attributeCount() > 0 && g->attributes()->type == GL_FLOAT) { + if (g->attributeCount() > 0 && g->attributes()->type == QSGGeometry::TypeFloat) { float x1 = 1e10, x2 = -1e10, y1=1e10, y2=-1e10; int stride = g->sizeOfVertex(); for (int i = 0; i < g->vertexCount(); ++i) { diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h index 9d14ae04df..349753a361 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.h +++ b/src/quick/scenegraph/coreapi/qsgnode.h @@ -204,6 +204,9 @@ public: const QMatrix4x4 *matrix() const { return m_matrix; } const QSGClipNode *clipList() const { return m_clip_list; } + void setMatrix(const QMatrix4x4 *m) { m_matrix = m; } + void setClipList(const QSGClipNode *c) { m_clip_list = c; } + protected: QSGBasicGeometryNode(NodeType type); QSGBasicGeometryNode(QSGBasicGeometryNodePrivate &dd, NodeType type); diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index ace10661c0..220e6ab212 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -39,11 +39,15 @@ #include "qsgrenderer_p.h" #include "qsgnodeupdater_p.h" - -#include <qopenglframebufferobject.h> - +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLFramebufferObject> +# include <QtGui/QOpenGLContext> +# include <QtGui/QOpenGLFunctions> +#endif #include <private/qquickprofiler_p.h> +#include <QtCore/QElapsedTimer> + QT_BEGIN_NAMESPACE static const bool qsg_sanity_check = qEnvironmentVariableIntValue("QSG_SANITY_CHECK"); @@ -63,19 +67,25 @@ int qt_sg_envInt(const char *name, int defaultValue) void QSGBindable::clear(QSGAbstractRenderer::ClearMode mode) const { +#ifndef QT_NO_OPENGL GLuint bits = 0; if (mode & QSGAbstractRenderer::ClearColorBuffer) bits |= GL_COLOR_BUFFER_BIT; if (mode & QSGAbstractRenderer::ClearDepthBuffer) bits |= GL_DEPTH_BUFFER_BIT; if (mode & QSGAbstractRenderer::ClearStencilBuffer) bits |= GL_STENCIL_BUFFER_BIT; QOpenGLContext::currentContext()->functions()->glClear(bits); +#else + Q_UNUSED(mode) +#endif } // Reactivate the color buffer after switching to the stencil. void QSGBindable::reactivate() const { +#ifndef QT_NO_OPENGL QOpenGLContext::currentContext()->functions()->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +#endif } - +#ifndef QT_NO_OPENGL QSGBindableFboId::QSGBindableFboId(GLuint id) : m_id(id) { @@ -86,7 +96,7 @@ void QSGBindableFboId::bind() const { QOpenGLContext::currentContext()->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_id); } - +#endif /*! \class QSGRenderer \brief The renderer class is the abstract baseclass use for rendering the @@ -169,8 +179,9 @@ bool QSGRenderer::isMirrored() const return matrix(0, 0) * matrix(1, 1) - matrix(0, 1) * matrix(1, 0) > 0; } -void QSGRenderer::renderScene(GLuint fboId) +void QSGRenderer::renderScene(uint fboId) { +#ifndef QT_NO_OPENGL if (fboId) { QSGBindableFboId bindable(fboId); renderScene(bindable); @@ -182,7 +193,11 @@ void QSGRenderer::renderScene(GLuint fboId) } bindable; renderScene(bindable); } +#else + Q_UNUSED(fboId) +#endif } + void QSGRenderer::renderScene(const QSGBindable &bindable) { if (!rootNode()) @@ -207,6 +222,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) bindTime = frameTimer.nsecsElapsed(); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame); +#ifndef QT_NO_OPENGL // Sanity check that attribute registers are disabled if (qsg_sanity_check) { GLint count = 0; @@ -219,6 +235,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) } } } +#endif render(); if (profileFrames) diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h index 5c7a32c161..94b78a85b4 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h @@ -86,14 +86,12 @@ public: bool isMirrored() const; void renderScene(const QSGBindable &bindable); - virtual void renderScene(GLuint fboId = 0) Q_DECL_OVERRIDE; + virtual void renderScene(uint fboId = 0) Q_DECL_OVERRIDE; virtual void nodeChanged(QSGNode *node, QSGNode::DirtyState state) Q_DECL_OVERRIDE; QSGNodeUpdater *nodeUpdater() const; void setNodeUpdater(QSGNodeUpdater *updater); - inline QSGMaterialShader::RenderState state(QSGMaterialShader::RenderState::DirtyStates dirty) const; - virtual void setCustomRenderMode(const QByteArray &) { }; void clearChangedFlag() { m_changed_emitted = false; } @@ -135,7 +133,7 @@ public: virtual void clear(QSGAbstractRenderer::ClearMode mode) const; virtual void reactivate() const; }; - +#ifndef QT_NO_OPENGL class QSGBindableFboId : public QSGBindable { public: @@ -144,7 +142,7 @@ public: private: GLuint m_id; }; - +#endif QSGMaterialShader::RenderState QSGRenderer::state(QSGMaterialShader::RenderState::DirtyStates dirty) const diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index eb6a846a81..e8ef6befcd 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -72,8 +72,11 @@ QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCach // this allows us to call pathForGlyph once and reuse the result. m_referenceFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(m_doubleGlyphResolution) * QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution)); Q_ASSERT(m_referenceFont.isValid()); - +#ifndef QT_NO_OPENGL m_coreProfile = (c->format().profile() == QSurfaceFormat::CoreProfile); +#else + Q_UNUSED(c) +#endif } QSGDistanceFieldGlyphCache::~QSGDistanceFieldGlyphCache() @@ -291,7 +294,7 @@ void QSGDistanceFieldGlyphCache::markGlyphsToRender(const QVector<glyph_t> &glyp m_pendingGlyphs.add(glyphs.at(i)); } -void QSGDistanceFieldGlyphCache::updateTexture(GLuint oldTex, GLuint newTex, const QSize &newTexSize) +void QSGDistanceFieldGlyphCache::updateTexture(uint oldTex, uint newTex, const QSize &newTexSize) { int count = m_textures.count(); for (int i = 0; i < count; ++i) { diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index 8579b0a57b..78bb07599f 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -210,7 +210,7 @@ public: virtual QImage toImage() const = 0; virtual void setLive(bool live) = 0; virtual void setRecursive(bool recursive) = 0; - virtual void setFormat(GLenum format) = 0; + virtual void setFormat(uint format) = 0; virtual void setHasMipmaps(bool mipmap) = 0; virtual void setDevicePixelRatio(qreal ratio) = 0; virtual void setMirrorHorizontal(bool mirror) = 0; @@ -295,7 +295,7 @@ public: }; struct Texture { - GLuint textureId; + uint textureId; QSize size; Texture() : textureId(0), size(QSize()) { } @@ -359,10 +359,10 @@ protected: void markGlyphsToRender(const QVector<glyph_t> &glyphs); inline void removeGlyph(glyph_t glyph); - void updateTexture(GLuint oldTex, GLuint newTex, const QSize &newTexSize); + void updateTexture(uint oldTex, uint newTex, const QSize &newTexSize); inline bool containsGlyph(glyph_t glyph); - GLuint textureIdForGlyph(glyph_t glyph) const; + uint textureIdForGlyph(glyph_t glyph) const; GlyphData &glyphData(glyph_t glyph); diff --git a/src/quick/scenegraph/qsgbasicglyphnode.cpp b/src/quick/scenegraph/qsgbasicglyphnode.cpp new file mode 100644 index 0000000000..38f650a82c --- /dev/null +++ b/src/quick/scenegraph/qsgbasicglyphnode.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgbasicglyphnode_p.h" +#include <qsgmaterial.h> // just so that we can safely do delete m_material in the dtor + +QT_BEGIN_NAMESPACE + +QSGBasicGlyphNode::QSGBasicGlyphNode() + : m_style(QQuickText::Normal) + , m_material(0) + , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) +{ + m_geometry.setDrawingMode(QSGGeometry::DrawTriangles); + setGeometry(&m_geometry); +} + +QSGBasicGlyphNode::~QSGBasicGlyphNode() +{ + delete m_material; +} + +void QSGBasicGlyphNode::setColor(const QColor &color) +{ + m_color = color; + if (m_material != 0) { + setMaterialColor(color); + markDirty(DirtyMaterial); + } +} + +void QSGBasicGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs) +{ + if (m_material != 0) + delete m_material; + + m_position = position; + m_glyphs = glyphs; + +#ifdef QSG_RUNTIME_DESCRIPTION + qsgnode_set_description(this, QLatin1String("glyphs")); +#endif +} + +void QSGBasicGlyphNode::setStyle(QQuickText::TextStyle style) +{ + if (m_style == style) + return; + m_style = style; +} + +void QSGBasicGlyphNode::setStyleColor(const QColor &color) +{ + if (m_styleColor == color) + return; + m_styleColor = color; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgbasicglyphnode_p.h b/src/quick/scenegraph/qsgbasicglyphnode_p.h new file mode 100644 index 0000000000..6c6e1d7cc6 --- /dev/null +++ b/src/quick/scenegraph/qsgbasicglyphnode_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGBASICGLYPHNODE_P_H +#define QSGBASICGLYPHNODE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +class QSGMaterial; + +class QSGBasicGlyphNode: public QSGGlyphNode +{ +public: + QSGBasicGlyphNode(); + virtual ~QSGBasicGlyphNode(); + + virtual QPointF baseLine() const { return m_baseLine; } + virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs); + virtual void setColor(const QColor &color); + + virtual void setPreferredAntialiasingMode(AntialiasingMode) { } + virtual void setStyle(QQuickText::TextStyle); + virtual void setStyleColor(const QColor &); + + virtual void setMaterialColor(const QColor &color) = 0; + virtual void update() = 0; + +protected: + QGlyphRun m_glyphs; + QPointF m_position; + QColor m_color; + QQuickText::TextStyle m_style; + QColor m_styleColor; + + QPointF m_baseLine; + QSGMaterial *m_material; + + QSGGeometry m_geometry; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/quick/scenegraph/qsgbasicimagenode.cpp b/src/quick/scenegraph/qsgbasicimagenode.cpp new file mode 100644 index 0000000000..0d33e2e24a --- /dev/null +++ b/src/quick/scenegraph/qsgbasicimagenode.cpp @@ -0,0 +1,530 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgbasicimagenode_p.h" + +#include <QtCore/qvarlengtharray.h> +#include <QtCore/qmath.h> + +QT_BEGIN_NAMESPACE + +namespace +{ + struct SmoothVertex + { + float x, y, u, v; + float dx, dy, du, dv; + }; + + const QSGGeometry::AttributeSet &smoothAttributeSet() + { + static QSGGeometry::Attribute data[] = { + QSGGeometry::Attribute::createWithSemantic(0, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::POSITION), + QSGGeometry::Attribute::createWithSemantic(1, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD), + QSGGeometry::Attribute::createWithSemantic(2, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD1), + QSGGeometry::Attribute::createWithSemantic(3, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD2) + }; + static QSGGeometry::AttributeSet attrs = { 4, sizeof(SmoothVertex), data }; + return attrs; + } +} + +QSGBasicImageNode::QSGBasicImageNode() + : m_innerSourceRect(0, 0, 1, 1) + , m_subSourceRect(0, 0, 1, 1) + , m_antialiasing(false) + , m_mirror(false) + , m_dirtyGeometry(false) + , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) + , m_dynamicTexture(nullptr) +{ + setGeometry(&m_geometry); + +#ifdef QSG_RUNTIME_DESCRIPTION + qsgnode_set_description(this, QLatin1String("image")); +#endif +} + +void QSGBasicImageNode::setTargetRect(const QRectF &rect) +{ + if (rect == m_targetRect) + return; + m_targetRect = rect; + m_dirtyGeometry = true; +} + +void QSGBasicImageNode::setInnerTargetRect(const QRectF &rect) +{ + if (rect == m_innerTargetRect) + return; + m_innerTargetRect = rect; + m_dirtyGeometry = true; +} + +void QSGBasicImageNode::setInnerSourceRect(const QRectF &rect) +{ + if (rect == m_innerSourceRect) + return; + m_innerSourceRect = rect; + m_dirtyGeometry = true; +} + +void QSGBasicImageNode::setSubSourceRect(const QRectF &rect) +{ + if (rect == m_subSourceRect) + return; + m_subSourceRect = rect; + m_dirtyGeometry = true; +} + +void QSGBasicImageNode::setTexture(QSGTexture *texture) +{ + Q_ASSERT(texture); + + setMaterialTexture(texture); + updateMaterialBlending(); + + markDirty(DirtyMaterial); + + // Because the texture can be a different part of the atlas, we need to update it... + m_dirtyGeometry = true; +} + +void QSGBasicImageNode::setAntialiasing(bool antialiasing) +{ + if (antialiasing == m_antialiasing) + return; + m_antialiasing = antialiasing; + if (m_antialiasing) { + setGeometry(new QSGGeometry(smoothAttributeSet(), 0)); + setFlag(OwnsGeometry, true); + } else { + setGeometry(&m_geometry); + setFlag(OwnsGeometry, false); + } + updateMaterialAntialiasing(); + m_dirtyGeometry = true; +} + +void QSGBasicImageNode::setMirror(bool mirror) +{ + if (mirror == m_mirror) + return; + m_mirror = mirror; + m_dirtyGeometry = true; +} + + +void QSGBasicImageNode::update() +{ + if (m_dirtyGeometry) + updateGeometry(); +} + +void QSGBasicImageNode::preprocess() +{ + bool doDirty = false; + QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(materialTexture()); + if (t) { + doDirty = t->updateTexture(); + if (doDirty) { + // The geometry may need updating. This is expensive however, so do + // it only when something relevant has changed. + if (t != m_dynamicTexture + || t->textureSize() != m_dynamicTextureSize + || t->normalizedTextureSubRect() != m_dynamicTextureSubRect) { + updateGeometry(); + m_dynamicTextureSize = t->textureSize(); + m_dynamicTextureSubRect = t->normalizedTextureSubRect(); + } + } + } + m_dynamicTexture = t; + + if (updateMaterialBlending()) + doDirty = true; + + if (doDirty) + markDirty(DirtyMaterial); +} + +namespace { + struct X { float x, tx; }; + struct Y { float y, ty; }; +} + +static inline void appendQuad(quint16 **indices, quint16 topLeft, quint16 topRight, + quint16 bottomLeft, quint16 bottomRight) +{ + *(*indices)++ = topLeft; + *(*indices)++ = bottomLeft; + *(*indices)++ = bottomRight; + *(*indices)++ = bottomRight; + *(*indices)++ = topRight; + *(*indices)++ = topLeft; +} + +void QSGBasicImageNode::updateGeometry() +{ + Q_ASSERT(!m_targetRect.isEmpty()); + const QSGTexture *t = materialTexture(); + if (!t) { + QSGGeometry *g = geometry(); + g->allocate(4); + g->setDrawingMode(QSGGeometry::DrawTriangleStrip); + memset(g->vertexData(), 0, g->sizeOfVertex() * 4); + } else { + QRectF sourceRect = t->normalizedTextureSubRect(); + + QRectF innerSourceRect(sourceRect.x() + m_innerSourceRect.x() * sourceRect.width(), + sourceRect.y() + m_innerSourceRect.y() * sourceRect.height(), + m_innerSourceRect.width() * sourceRect.width(), + m_innerSourceRect.height() * sourceRect.height()); + + bool hasMargins = m_targetRect != m_innerTargetRect; + + int floorLeft = qFloor(m_subSourceRect.left()); + int ceilRight = qCeil(m_subSourceRect.right()); + int floorTop = qFloor(m_subSourceRect.top()); + int ceilBottom = qCeil(m_subSourceRect.bottom()); + int hTiles = ceilRight - floorLeft; + int vTiles = ceilBottom - floorTop; + + bool hasTiles = hTiles != 1 || vTiles != 1; + bool fullTexture = innerSourceRect == QRectF(0, 0, 1, 1); + + // An image can be rendered as a single quad if: + // - There are no margins, and either: + // - the image isn't repeated + // - the source rectangle fills the entire texture so that texture wrapping can be used, + // and NPOT is supported + if (!hasMargins && (!hasTiles || (fullTexture && supportsWrap(t->textureSize())))) { + QRectF sr; + if (!fullTexture) { + sr = QRectF(innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(), + innerSourceRect.y() + (m_subSourceRect.top() - floorTop) * innerSourceRect.height(), + m_subSourceRect.width() * innerSourceRect.width(), + m_subSourceRect.height() * innerSourceRect.height()); + } else { + sr = QRectF(m_subSourceRect.left() - floorLeft, m_subSourceRect.top() - floorTop, + m_subSourceRect.width(), m_subSourceRect.height()); + } + if (m_mirror) { + qreal oldLeft = sr.left(); + sr.setLeft(sr.right()); + sr.setRight(oldLeft); + } + + if (m_antialiasing) { + QSGGeometry *g = geometry(); + Q_ASSERT(g != &m_geometry); + g->allocate(8, 14); + g->setDrawingMode(QSGGeometry::DrawTriangleStrip); + SmoothVertex *vertices = reinterpret_cast<SmoothVertex *>(g->vertexData()); + float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height()) + ? m_targetRect.width() : m_targetRect.height()) * 0.5f; + float sx = float(sr.width() / m_targetRect.width()); + float sy = float(sr.height() / m_targetRect.height()); + for (int d = -1; d <= 1; d += 2) { + for (int j = 0; j < 2; ++j) { + for (int i = 0; i < 2; ++i, ++vertices) { + vertices->x = m_targetRect.x() + i * m_targetRect.width(); + vertices->y = m_targetRect.y() + j * m_targetRect.height(); + vertices->u = sr.x() + i * sr.width(); + vertices->v = sr.y() + j * sr.height(); + vertices->dx = (i == 0 ? delta : -delta) * d; + vertices->dy = (j == 0 ? delta : -delta) * d; + vertices->du = (d < 0 ? 0 : vertices->dx * sx); + vertices->dv = (d < 0 ? 0 : vertices->dy * sy); + } + } + } + Q_ASSERT(vertices - g->vertexCount() == g->vertexData()); + static const quint16 indices[] = { + 0, 4, 1, 5, 3, 7, 2, 6, 0, 4, + 4, 6, 5, 7 + }; + Q_ASSERT(g->sizeOfIndex() * g->indexCount() == sizeof(indices)); + memcpy(g->indexDataAsUShort(), indices, sizeof(indices)); + } else { + m_geometry.allocate(4); + m_geometry.setDrawingMode(QSGGeometry::DrawTriangleStrip); + QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_targetRect, sr); + } + } else { + int hCells = hTiles; + int vCells = vTiles; + if (m_innerTargetRect.width() == 0) + hCells = 0; + if (m_innerTargetRect.left() != m_targetRect.left()) + ++hCells; + if (m_innerTargetRect.right() != m_targetRect.right()) + ++hCells; + if (m_innerTargetRect.height() == 0) + vCells = 0; + if (m_innerTargetRect.top() != m_targetRect.top()) + ++vCells; + if (m_innerTargetRect.bottom() != m_targetRect.bottom()) + ++vCells; + QVarLengthArray<X, 32> xData(2 * hCells); + QVarLengthArray<Y, 32> yData(2 * vCells); + X *xs = xData.data(); + Y *ys = yData.data(); + + if (m_innerTargetRect.left() != m_targetRect.left()) { + xs[0].x = m_targetRect.left(); + xs[0].tx = sourceRect.left(); + xs[1].x = m_innerTargetRect.left(); + xs[1].tx = innerSourceRect.left(); + xs += 2; + } + if (m_innerTargetRect.width() != 0) { + xs[0].x = m_innerTargetRect.left(); + xs[0].tx = innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(); + ++xs; + float b = m_innerTargetRect.width() / m_subSourceRect.width(); + float a = m_innerTargetRect.x() - m_subSourceRect.x() * b; + for (int i = floorLeft + 1; i <= ceilRight - 1; ++i) { + xs[0].x = xs[1].x = a + b * i; + xs[0].tx = innerSourceRect.right(); + xs[1].tx = innerSourceRect.left(); + xs += 2; + } + xs[0].x = m_innerTargetRect.right(); + xs[0].tx = innerSourceRect.x() + (m_subSourceRect.right() - ceilRight + 1) * innerSourceRect.width(); + ++xs; + } + if (m_innerTargetRect.right() != m_targetRect.right()) { + xs[0].x = m_innerTargetRect.right(); + xs[0].tx = innerSourceRect.right(); + xs[1].x = m_targetRect.right(); + xs[1].tx = sourceRect.right(); + xs += 2; + } + Q_ASSERT(xs == xData.data() + xData.size()); + if (m_mirror) { + float leftPlusRight = m_targetRect.left() + m_targetRect.right(); + int count = xData.size(); + xs = xData.data(); + for (int i = 0; i < count >> 1; ++i) + qSwap(xs[i], xs[count - 1 - i]); + for (int i = 0; i < count; ++i) + xs[i].x = leftPlusRight - xs[i].x; + } + + if (m_innerTargetRect.top() != m_targetRect.top()) { + ys[0].y = m_targetRect.top(); + ys[0].ty = sourceRect.top(); + ys[1].y = m_innerTargetRect.top(); + ys[1].ty = innerSourceRect.top(); + ys += 2; + } + if (m_innerTargetRect.height() != 0) { + ys[0].y = m_innerTargetRect.top(); + ys[0].ty = innerSourceRect.y() + (m_subSourceRect.top() - floorTop) * innerSourceRect.height(); + ++ys; + float b = m_innerTargetRect.height() / m_subSourceRect.height(); + float a = m_innerTargetRect.y() - m_subSourceRect.y() * b; + for (int i = floorTop + 1; i <= ceilBottom - 1; ++i) { + ys[0].y = ys[1].y = a + b * i; + ys[0].ty = innerSourceRect.bottom(); + ys[1].ty = innerSourceRect.top(); + ys += 2; + } + ys[0].y = m_innerTargetRect.bottom(); + ys[0].ty = innerSourceRect.y() + (m_subSourceRect.bottom() - ceilBottom + 1) * innerSourceRect.height(); + ++ys; + } + if (m_innerTargetRect.bottom() != m_targetRect.bottom()) { + ys[0].y = m_innerTargetRect.bottom(); + ys[0].ty = innerSourceRect.bottom(); + ys[1].y = m_targetRect.bottom(); + ys[1].ty = sourceRect.bottom(); + ys += 2; + } + Q_ASSERT(ys == yData.data() + yData.size()); + + if (m_antialiasing) { + QSGGeometry *g = geometry(); + Q_ASSERT(g != &m_geometry); + + g->allocate(hCells * vCells * 4 + (hCells + vCells - 1) * 4, + hCells * vCells * 6 + (hCells + vCells) * 12); + g->setDrawingMode(QSGGeometry::DrawTriangles); + SmoothVertex *vertices = reinterpret_cast<SmoothVertex *>(g->vertexData()); + memset(vertices, 0, g->vertexCount() * g->sizeOfVertex()); + quint16 *indices = g->indexDataAsUShort(); + + // The deltas are how much the fuzziness can reach into the image. + // Only the border vertices are moved by the vertex shader, so the fuzziness + // can't reach further into the image than the closest interior vertices. + float leftDx = xData.at(1).x - xData.at(0).x; + float rightDx = xData.at(xData.size() - 1).x - xData.at(xData.size() - 2).x; + float topDy = yData.at(1).y - yData.at(0).y; + float bottomDy = yData.at(yData.size() - 1).y - yData.at(yData.size() - 2).y; + + float leftDu = xData.at(1).tx - xData.at(0).tx; + float rightDu = xData.at(xData.size() - 1).tx - xData.at(xData.size() - 2).tx; + float topDv = yData.at(1).ty - yData.at(0).ty; + float bottomDv = yData.at(yData.size() - 1).ty - yData.at(yData.size() - 2).ty; + + if (hCells == 1) { + leftDx = rightDx *= 0.5f; + leftDu = rightDu *= 0.5f; + } + if (vCells == 1) { + topDy = bottomDy *= 0.5f; + topDv = bottomDv *= 0.5f; + } + + // This delta is how much the fuzziness can reach out from the image. + float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height()) + ? m_targetRect.width() : m_targetRect.height()) * 0.5f; + + quint16 index = 0; + ys = yData.data(); + for (int j = 0; j < vCells; ++j, ys += 2) { + xs = xData.data(); + bool isTop = j == 0; + bool isBottom = j == vCells - 1; + for (int i = 0; i < hCells; ++i, xs += 2) { + bool isLeft = i == 0; + bool isRight = i == hCells - 1; + + SmoothVertex *v = vertices + index; + + quint16 topLeft = index; + for (int k = (isTop || isLeft ? 2 : 1); k--; ++v, ++index) { + v->x = xs[0].x; + v->u = xs[0].tx; + v->y = ys[0].y; + v->v = ys[0].ty; + } + + quint16 topRight = index; + for (int k = (isTop || isRight ? 2 : 1); k--; ++v, ++index) { + v->x = xs[1].x; + v->u = xs[1].tx; + v->y = ys[0].y; + v->v = ys[0].ty; + } + + quint16 bottomLeft = index; + for (int k = (isBottom || isLeft ? 2 : 1); k--; ++v, ++index) { + v->x = xs[0].x; + v->u = xs[0].tx; + v->y = ys[1].y; + v->v = ys[1].ty; + } + + quint16 bottomRight = index; + for (int k = (isBottom || isRight ? 2 : 1); k--; ++v, ++index) { + v->x = xs[1].x; + v->u = xs[1].tx; + v->y = ys[1].y; + v->v = ys[1].ty; + } + + appendQuad(&indices, topLeft, topRight, bottomLeft, bottomRight); + + if (isTop) { + vertices[topLeft].dy = vertices[topRight].dy = topDy; + vertices[topLeft].dv = vertices[topRight].dv = topDv; + vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -delta; + appendQuad(&indices, topLeft + 1, topRight + 1, topLeft, topRight); + } + + if (isBottom) { + vertices[bottomLeft].dy = vertices[bottomRight].dy = -bottomDy; + vertices[bottomLeft].dv = vertices[bottomRight].dv = -bottomDv; + vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = delta; + appendQuad(&indices, bottomLeft, bottomRight, bottomLeft + 1, bottomRight + 1); + } + + if (isLeft) { + vertices[topLeft].dx = vertices[bottomLeft].dx = leftDx; + vertices[topLeft].du = vertices[bottomLeft].du = leftDu; + vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -delta; + appendQuad(&indices, topLeft + 1, topLeft, bottomLeft + 1, bottomLeft); + } + + if (isRight) { + vertices[topRight].dx = vertices[bottomRight].dx = -rightDx; + vertices[topRight].du = vertices[bottomRight].du = -rightDu; + vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = delta; + appendQuad(&indices, topRight, topRight + 1, bottomRight, bottomRight + 1); + } + } + } + + Q_ASSERT(index == g->vertexCount()); + Q_ASSERT(indices - g->indexCount() == g->indexData()); + } else { + m_geometry.allocate(hCells * vCells * 4, hCells * vCells * 6); + m_geometry.setDrawingMode(QSGGeometry::DrawTriangles); + QSGGeometry::TexturedPoint2D *vertices = m_geometry.vertexDataAsTexturedPoint2D(); + ys = yData.data(); + for (int j = 0; j < vCells; ++j, ys += 2) { + xs = xData.data(); + for (int i = 0; i < hCells; ++i, xs += 2) { + vertices[0].x = vertices[2].x = xs[0].x; + vertices[0].tx = vertices[2].tx = xs[0].tx; + vertices[1].x = vertices[3].x = xs[1].x; + vertices[1].tx = vertices[3].tx = xs[1].tx; + + vertices[0].y = vertices[1].y = ys[0].y; + vertices[0].ty = vertices[1].ty = ys[0].ty; + vertices[2].y = vertices[3].y = ys[1].y; + vertices[2].ty = vertices[3].ty = ys[1].ty; + + vertices += 4; + } + } + + quint16 *indices = m_geometry.indexDataAsUShort(); + for (int i = 0; i < 4 * vCells * hCells; i += 4) + appendQuad(&indices, i, i + 1, i + 2, i + 3); + } + } + } + markDirty(DirtyGeometry); + m_dirtyGeometry = false; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgbasicimagenode_p.h b/src/quick/scenegraph/qsgbasicimagenode_p.h new file mode 100644 index 0000000000..288b6c23f0 --- /dev/null +++ b/src/quick/scenegraph/qsgbasicimagenode_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGBASICIMAGENODE_P_H +#define QSGBASICIMAGENODE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICK_PRIVATE_EXPORT QSGBasicImageNode : public QSGImageNode +{ +public: + QSGBasicImageNode(); + + void setTargetRect(const QRectF &rect) override; + void setInnerTargetRect(const QRectF &rect) override; + void setInnerSourceRect(const QRectF &rect) override; + void setSubSourceRect(const QRectF &rect) override; + void setTexture(QSGTexture *texture) override; + void setAntialiasing(bool antialiasing) override; + void setMirror(bool mirror) override; + void update() override; + void preprocess() override; + +protected: + virtual void updateMaterialAntialiasing() = 0; + virtual void setMaterialTexture(QSGTexture *texture) = 0; + virtual QSGTexture *materialTexture() const = 0; + virtual bool updateMaterialBlending() = 0; + virtual bool supportsWrap(const QSize &size) const = 0; + + void updateGeometry(); + + QRectF m_targetRect; + QRectF m_innerTargetRect; + QRectF m_innerSourceRect; + QRectF m_subSourceRect; + + uint m_antialiasing : 1; + uint m_mirror : 1; + uint m_dirtyGeometry : 1; + + QSGGeometry m_geometry; + + QSGDynamicTexture *m_dynamicTexture; + QSize m_dynamicTextureSize; + QRectF m_dynamicTextureSubRect; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/quick/scenegraph/qsgbasicrectanglenode.cpp b/src/quick/scenegraph/qsgbasicrectanglenode.cpp new file mode 100644 index 0000000000..14d2dc9677 --- /dev/null +++ b/src/quick/scenegraph/qsgbasicrectanglenode.cpp @@ -0,0 +1,687 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgbasicrectanglenode_p.h" + +#include <QtCore/qmath.h> + +QT_BEGIN_NAMESPACE + +namespace +{ + struct Color4ub + { + unsigned char r, g, b, a; + }; + + Color4ub operator *(Color4ub c, float t) { c.a *= t; c.r *= t; c.g *= t; c.b *= t; return c; } + Color4ub operator +(Color4ub a, Color4ub b) { a.a += b.a; a.r += b.r; a.g += b.g; a.b += b.b; return a; } + + inline Color4ub colorToColor4ub(const QColor &c) + { + Color4ub color = { uchar(qRound(c.redF() * c.alphaF() * 255)), + uchar(qRound(c.greenF() * c.alphaF() * 255)), + uchar(qRound(c.blueF() * c.alphaF() * 255)), + uchar(qRound(c.alphaF() * 255)) + }; + return color; + } + + // Same layout as QSGGeometry::ColoredPoint2D, but uses Color4ub for convenience. + struct Vertex + { + float x, y; + Color4ub color; + void set(float nx, float ny, Color4ub ncolor) + { + x = nx; y = ny; color = ncolor; + } + }; + + struct SmoothVertex : public Vertex + { + float dx, dy; + void set(float nx, float ny, Color4ub ncolor, float ndx, float ndy) + { + Vertex::set(nx, ny, ncolor); + dx = ndx; dy = ndy; + } + }; + + const QSGGeometry::AttributeSet &smoothAttributeSet() + { + static QSGGeometry::Attribute data[] = { + QSGGeometry::Attribute::createWithSemantic(0, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::POSITION), + QSGGeometry::Attribute::createWithSemantic(1, 4, QSGGeometry::TypeUnsignedByte, QSGGeometry::Attribute::COLOR), + QSGGeometry::Attribute::createWithSemantic(2, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD) + }; + static QSGGeometry::AttributeSet attrs = { 3, sizeof(SmoothVertex), data }; + return attrs; + } +} + +QSGBasicRectangleNode::QSGBasicRectangleNode() + : m_radius(0) + , m_pen_width(0) + , m_aligned(true) + , m_antialiasing(false) + , m_gradient_is_opaque(true) + , m_dirty_geometry(false) + , m_geometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 0) +{ + setGeometry(&m_geometry); + +#ifdef QSG_RUNTIME_DESCRIPTION + qsgnode_set_description(this, QLatin1String("rectangle")); +#endif +} + +void QSGBasicRectangleNode::setRect(const QRectF &rect) +{ + if (rect == m_rect) + return; + m_rect = rect; + m_dirty_geometry = true; +} + +void QSGBasicRectangleNode::setColor(const QColor &color) +{ + if (color == m_color) + return; + m_color = color; + if (m_gradient_stops.isEmpty()) + m_dirty_geometry = true; +} + +void QSGBasicRectangleNode::setPenColor(const QColor &color) +{ + if (color == m_border_color) + return; + m_border_color = color; + if (m_pen_width > 0) + m_dirty_geometry = true; +} + +void QSGBasicRectangleNode::setPenWidth(qreal width) +{ + if (width == m_pen_width) + return; + m_pen_width = width; + m_dirty_geometry = true; +} + + +void QSGBasicRectangleNode::setGradientStops(const QGradientStops &stops) +{ + if (stops.constData() == m_gradient_stops.constData()) + return; + + m_gradient_stops = stops; + + m_gradient_is_opaque = true; + for (int i = 0; i < stops.size(); ++i) + m_gradient_is_opaque &= stops.at(i).second.alpha() == 0xff; + m_dirty_geometry = true; +} + +void QSGBasicRectangleNode::setRadius(qreal radius) +{ + if (radius == m_radius) + return; + m_radius = radius; + m_dirty_geometry = true; +} + +void QSGBasicRectangleNode::setAntialiasing(bool antialiasing) +{ + if (!supportsAntialiasing()) + return; + + if (antialiasing == m_antialiasing) + return; + m_antialiasing = antialiasing; + if (m_antialiasing) { + setGeometry(new QSGGeometry(smoothAttributeSet(), 0)); + setFlag(OwnsGeometry, true); + } else { + setGeometry(&m_geometry); + setFlag(OwnsGeometry, false); + } + updateMaterialAntialiasing(); + m_dirty_geometry = true; +} + +void QSGBasicRectangleNode::setAligned(bool aligned) +{ + if (aligned == m_aligned) + return; + m_aligned = aligned; + m_dirty_geometry = true; +} + +void QSGBasicRectangleNode::update() +{ + if (m_dirty_geometry) { + updateGeometry(); + m_dirty_geometry = false; + + QSGNode::DirtyState state = QSGNode::DirtyGeometry; + updateMaterialBlending(&state); + markDirty(state); + } +} + +void QSGBasicRectangleNode::updateGeometry() +{ + float width = float(m_rect.width()); + float height = float(m_rect.height()); + float penWidth = qMin(qMin(width, height) * 0.5f, float(m_pen_width)); + + if (m_aligned) + penWidth = qRound(penWidth); + + QSGGeometry *g = geometry(); + g->setDrawingMode(QSGGeometry::DrawTriangleStrip); + int vertexStride = g->sizeOfVertex(); + + union { + Vertex *vertices; + SmoothVertex *smoothVertices; + }; + + Color4ub fillColor = colorToColor4ub(m_color); + Color4ub borderColor = colorToColor4ub(m_border_color); + Color4ub transparent = { 0, 0, 0, 0 }; + const QGradientStops &stops = m_gradient_stops; + + int nextGradientStop = 0; + float gradientPos = penWidth / height; + while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos) + ++nextGradientStop; + int lastGradientStop = stops.size() - 1; + float lastGradientPos = 1.0f - penWidth / height; + while (lastGradientStop >= nextGradientStop && stops.at(lastGradientStop).first >= lastGradientPos) + --lastGradientStop; + int gradientIntersections = (lastGradientStop - nextGradientStop + 1); + + if (m_radius > 0) { + // Rounded corners. + + // Radius should never exceeds half of the width or half of the height + float radius = qMin(qMin(width, height) * 0.5f, float(m_radius)); + QRectF innerRect = m_rect; + innerRect.adjust(radius, radius, -radius, -radius); + + float innerRadius = radius - penWidth * 1.0f; + float outerRadius = radius; + float delta = qMin(width, height) * 0.5f; + + // Number of segments per corner, approximately one per 3 pixels. + int segments = qBound(3, qCeil(outerRadius * (M_PI / 6)), 18); + + /* + + --+--__ + --+--__--__ + | --__--__ + | seg --__--+ + --+-__ ment _+ \ + --+-__--__ - \ \ + --__--+ se \ \ + + \ g \ \ + \ \ m \ \ + -----------+--+ e \ \ <- gradient line + \ \ nt\ \ + fill +--+----+--+ + | | | | + border + inner AA outer AA (AA = antialiasing) + + */ + + int innerVertexCount = (segments + 1) * 4 + gradientIntersections * 2; + int outerVertexCount = (segments + 1) * 4; + int vertexCount = innerVertexCount; + if (m_antialiasing || penWidth) + vertexCount += innerVertexCount; + if (penWidth) + vertexCount += outerVertexCount; + if (m_antialiasing && penWidth) + vertexCount += outerVertexCount; + + int fillIndexCount = innerVertexCount; + int innerAAIndexCount = innerVertexCount * 2 + 2; + int borderIndexCount = innerVertexCount * 2 + 2; + int outerAAIndexCount = outerVertexCount * 2 + 2; + int indexCount = 0; + int fillHead = 0; + int innerAAHead = 0; + int innerAATail = 0; + int borderHead = 0; + int borderTail = 0; + int outerAAHead = 0; + int outerAATail = 0; + bool hasFill = m_color.alpha() > 0 || !stops.isEmpty(); + if (hasFill) + indexCount += fillIndexCount; + if (m_antialiasing) { + innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1; + indexCount += innerAAIndexCount; + } + if (penWidth) { + borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1; + indexCount += borderIndexCount; + } + if (m_antialiasing && penWidth) { + outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1; + indexCount += outerAAIndexCount; + } + + g->allocate(vertexCount, indexCount); + vertices = reinterpret_cast<Vertex *>(g->vertexData()); + memset(vertices, 0, vertexCount * vertexStride); + quint16 *indices = g->indexDataAsUShort(); + quint16 index = 0; + + float py = 0; // previous inner y-coordinate. + float plx = 0; // previous inner left x-coordinate. + float prx = 0; // previous inner right x-coordinate. + + float angle = 0.5f * float(M_PI) / segments; + float cosStep = qFastCos(angle); + float sinStep = qFastSin(angle); + + for (int part = 0; part < 2; ++part) { + float c = 1 - part; + float s = part; + for (int i = 0; i <= segments; ++i) { + float y, lx, rx; + if (innerRadius > 0) { + y = (part ? innerRect.bottom() : innerRect.top()) - innerRadius * c; // current inner y-coordinate. + lx = innerRect.left() - innerRadius * s; // current inner left x-coordinate. + rx = innerRect.right() + innerRadius * s; // current inner right x-coordinate. + gradientPos = ((part ? innerRect.height() : 0) + radius - innerRadius * c) / height; + } else { + y = (part ? innerRect.bottom() + innerRadius : innerRect.top() - innerRadius); // current inner y-coordinate. + lx = innerRect.left() - innerRadius; // current inner left x-coordinate. + rx = innerRect.right() + innerRadius; // current inner right x-coordinate. + gradientPos = ((part ? innerRect.height() + innerRadius : -innerRadius) + radius) / height; + } + float Y = (part ? innerRect.bottom() : innerRect.top()) - outerRadius * c; // current outer y-coordinate. + float lX = innerRect.left() - outerRadius * s; // current outer left x-coordinate. + float rX = innerRect.right() + outerRadius * s; // current outer right x-coordinate. + + while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) { + // Insert vertices at gradient stops. + float gy = (innerRect.top() - radius) + stops.at(nextGradientStop).first * height; + float t = (gy - py) / (y - py); + float glx = plx * (1 - t) + t * lx; + float grx = prx * (1 - t) + t * rx; + + fillColor = colorToColor4ub(stops.at(nextGradientStop).second); + + if (hasFill) { + indices[fillHead++] = index; + indices[fillHead++] = index + 1; + } + + if (penWidth) { + --borderHead; + indices[borderHead] = indices[borderHead + 2]; + indices[--borderHead] = index + 2; + indices[borderTail++] = index + 3; + indices[borderTail] = indices[borderTail - 2]; + ++borderTail; + } + + if (m_antialiasing) { + indices[--innerAAHead] = index + 2; + indices[--innerAAHead] = index; + indices[innerAATail++] = index + 1; + indices[innerAATail++] = index + 3; + + bool lower = stops.at(nextGradientStop).first > 0.5f; + float dy = lower ? qMin(0.0f, height - gy - delta) : qMax(0.0f, delta - gy); + smoothVertices[index++].set(grx, gy, fillColor, width - grx - delta, dy); + smoothVertices[index++].set(glx, gy, fillColor, delta - glx, dy); + if (penWidth) { + smoothVertices[index++].set(grx, gy, borderColor, 0.49f * penWidth * s, -0.49f * penWidth * c); + smoothVertices[index++].set(glx, gy, borderColor, -0.49f * penWidth * s, -0.49f * penWidth * c); + } else { + dy = lower ? delta : -delta; + smoothVertices[index++].set(grx, gy, transparent, delta, dy); + smoothVertices[index++].set(glx, gy, transparent, -delta, dy); + } + } else { + vertices[index++].set(grx, gy, fillColor); + vertices[index++].set(glx, gy, fillColor); + if (penWidth) { + vertices[index++].set(grx, gy, borderColor); + vertices[index++].set(glx, gy, borderColor); + } + } + ++nextGradientStop; + } + + if (!stops.isEmpty()) { + if (nextGradientStop == 0) { + fillColor = colorToColor4ub(stops.at(0).second); + } else if (nextGradientStop == stops.size()) { + fillColor = colorToColor4ub(stops.last().second); + } else { + const QGradientStop &prev = stops.at(nextGradientStop - 1); + const QGradientStop &next = stops.at(nextGradientStop); + float t = (gradientPos - prev.first) / (next.first - prev.first); + fillColor = colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t; + } + } + + if (hasFill) { + indices[fillHead++] = index; + indices[fillHead++] = index + 1; + } + + if (penWidth) { + indices[--borderHead] = index + 4; + indices[--borderHead] = index + 2; + indices[borderTail++] = index + 3; + indices[borderTail++] = index + 5; + } + + if (m_antialiasing) { + indices[--innerAAHead] = index + 2; + indices[--innerAAHead] = index; + indices[innerAATail++] = index + 1; + indices[innerAATail++] = index + 3; + + float dy = part ? qMin(0.0f, height - y - delta) : qMax(0.0f, delta - y); + smoothVertices[index++].set(rx, y, fillColor, width - rx - delta, dy); + smoothVertices[index++].set(lx, y, fillColor, delta - lx, dy); + + dy = part ? delta : -delta; + if (penWidth) { + smoothVertices[index++].set(rx, y, borderColor, 0.49f * penWidth * s, -0.49f * penWidth * c); + smoothVertices[index++].set(lx, y, borderColor, -0.49f * penWidth * s, -0.49f * penWidth * c); + smoothVertices[index++].set(rX, Y, borderColor, -0.49f * penWidth * s, 0.49f * penWidth * c); + smoothVertices[index++].set(lX, Y, borderColor, 0.49f * penWidth * s, 0.49f * penWidth * c); + smoothVertices[index++].set(rX, Y, transparent, delta, dy); + smoothVertices[index++].set(lX, Y, transparent, -delta, dy); + + indices[--outerAAHead] = index - 2; + indices[--outerAAHead] = index - 4; + indices[outerAATail++] = index - 3; + indices[outerAATail++] = index - 1; + } else { + smoothVertices[index++].set(rx, y, transparent, delta, dy); + smoothVertices[index++].set(lx, y, transparent, -delta, dy); + } + } else { + vertices[index++].set(rx, y, fillColor); + vertices[index++].set(lx, y, fillColor); + if (penWidth) { + vertices[index++].set(rx, y, borderColor); + vertices[index++].set(lx, y, borderColor); + vertices[index++].set(rX, Y, borderColor); + vertices[index++].set(lX, Y, borderColor); + } + } + + py = y; + plx = lx; + prx = rx; + + // Rotate + qreal tmp = c; + c = c * cosStep - s * sinStep; + s = s * cosStep + tmp * sinStep; + } + } + Q_ASSERT(index == vertexCount); + + // Close the triangle strips. + if (m_antialiasing) { + indices[--innerAAHead] = indices[innerAATail - 1]; + indices[--innerAAHead] = indices[innerAATail - 2]; + Q_ASSERT(innerAATail <= indexCount); + } + if (penWidth) { + indices[--borderHead] = indices[borderTail - 1]; + indices[--borderHead] = indices[borderTail - 2]; + Q_ASSERT(borderTail <= indexCount); + } + if (m_antialiasing && penWidth) { + indices[--outerAAHead] = indices[outerAATail - 1]; + indices[--outerAAHead] = indices[outerAATail - 2]; + Q_ASSERT(outerAATail == indexCount); + } + } else { + // Straight corners. + QRectF innerRect = m_rect; + QRectF outerRect = m_rect; + + if (penWidth) + innerRect.adjust(1.0f * penWidth, 1.0f * penWidth, -1.0f * penWidth, -1.0f * penWidth); + + float delta = qMin(width, height) * 0.5f; + int innerVertexCount = 4 + gradientIntersections * 2; + int outerVertexCount = 4; + int vertexCount = innerVertexCount; + if (m_antialiasing || penWidth) + vertexCount += innerVertexCount; + if (penWidth) + vertexCount += outerVertexCount; + if (m_antialiasing && penWidth) + vertexCount += outerVertexCount; + + int fillIndexCount = innerVertexCount; + int innerAAIndexCount = innerVertexCount * 2 + 2; + int borderIndexCount = innerVertexCount * 2 + 2; + int outerAAIndexCount = outerVertexCount * 2 + 2; + int indexCount = 0; + int fillHead = 0; + int innerAAHead = 0; + int innerAATail = 0; + int borderHead = 0; + int borderTail = 0; + int outerAAHead = 0; + int outerAATail = 0; + bool hasFill = m_color.alpha() > 0 || !stops.isEmpty(); + if (hasFill) + indexCount += fillIndexCount; + if (m_antialiasing) { + innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1; + indexCount += innerAAIndexCount; + } + if (penWidth) { + borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1; + indexCount += borderIndexCount; + } + if (m_antialiasing && penWidth) { + outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1; + indexCount += outerAAIndexCount; + } + + g->allocate(vertexCount, indexCount); + vertices = reinterpret_cast<Vertex *>(g->vertexData()); + memset(vertices, 0, vertexCount * vertexStride); + quint16 *indices = g->indexDataAsUShort(); + quint16 index = 0; + + float lx = innerRect.left(); + float rx = innerRect.right(); + float lX = outerRect.left(); + float rX = outerRect.right(); + + for (int part = -1; part <= 1; part += 2) { + float y = (part == 1 ? innerRect.bottom() : innerRect.top()); + float Y = (part == 1 ? outerRect.bottom() : outerRect.top()); + gradientPos = (y - innerRect.top() + penWidth) / height; + + while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) { + // Insert vertices at gradient stops. + float gy = (innerRect.top() - penWidth) + stops.at(nextGradientStop).first * height; + + fillColor = colorToColor4ub(stops.at(nextGradientStop).second); + + if (hasFill) { + indices[fillHead++] = index; + indices[fillHead++] = index + 1; + } + + if (penWidth) { + --borderHead; + indices[borderHead] = indices[borderHead + 2]; + indices[--borderHead] = index + 2; + indices[borderTail++] = index + 3; + indices[borderTail] = indices[borderTail - 2]; + ++borderTail; + } + + if (m_antialiasing) { + indices[--innerAAHead] = index + 2; + indices[--innerAAHead] = index; + indices[innerAATail++] = index + 1; + indices[innerAATail++] = index + 3; + + bool lower = stops.at(nextGradientStop).first > 0.5f; + float dy = lower ? qMin(0.0f, height - gy - delta) : qMax(0.0f, delta - gy); + smoothVertices[index++].set(rx, gy, fillColor, width - rx - delta, dy); + smoothVertices[index++].set(lx, gy, fillColor, delta - lx, dy); + if (penWidth) { + smoothVertices[index++].set(rx, gy, borderColor, 0.49f * penWidth, (lower ? 0.49f : -0.49f) * penWidth); + smoothVertices[index++].set(lx, gy, borderColor, -0.49f * penWidth, (lower ? 0.49f : -0.49f) * penWidth); + } else { + smoothVertices[index++].set(rx, gy, transparent, delta, lower ? delta : -delta); + smoothVertices[index++].set(lx, gy, transparent, -delta, lower ? delta : -delta); + } + } else { + vertices[index++].set(rx, gy, fillColor); + vertices[index++].set(lx, gy, fillColor); + if (penWidth) { + vertices[index++].set(rx, gy, borderColor); + vertices[index++].set(lx, gy, borderColor); + } + } + ++nextGradientStop; + } + + if (!stops.isEmpty()) { + if (nextGradientStop == 0) { + fillColor = colorToColor4ub(stops.at(0).second); + } else if (nextGradientStop == stops.size()) { + fillColor = colorToColor4ub(stops.last().second); + } else { + const QGradientStop &prev = stops.at(nextGradientStop - 1); + const QGradientStop &next = stops.at(nextGradientStop); + float t = (gradientPos - prev.first) / (next.first - prev.first); + fillColor = colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t; + } + } + + if (hasFill) { + indices[fillHead++] = index; + indices[fillHead++] = index + 1; + } + + if (penWidth) { + indices[--borderHead] = index + 4; + indices[--borderHead] = index + 2; + indices[borderTail++] = index + 3; + indices[borderTail++] = index + 5; + } + + if (m_antialiasing) { + indices[--innerAAHead] = index + 2; + indices[--innerAAHead] = index; + indices[innerAATail++] = index + 1; + indices[innerAATail++] = index + 3; + + float dy = part == 1 ? qMin(0.0f, height - y - delta) : qMax(0.0f, delta - y); + smoothVertices[index++].set(rx, y, fillColor, width - rx - delta, dy); + smoothVertices[index++].set(lx, y, fillColor, delta - lx, dy); + + if (penWidth) { + smoothVertices[index++].set(rx, y, borderColor, 0.49f * penWidth, 0.49f * penWidth * part); + smoothVertices[index++].set(lx, y, borderColor, -0.49f * penWidth, 0.49f * penWidth * part); + smoothVertices[index++].set(rX, Y, borderColor, -0.49f * penWidth, -0.49f * penWidth * part); + smoothVertices[index++].set(lX, Y, borderColor, 0.49f * penWidth, -0.49f * penWidth * part); + smoothVertices[index++].set(rX, Y, transparent, delta, delta * part); + smoothVertices[index++].set(lX, Y, transparent, -delta, delta * part); + + indices[--outerAAHead] = index - 2; + indices[--outerAAHead] = index - 4; + indices[outerAATail++] = index - 3; + indices[outerAATail++] = index - 1; + } else { + smoothVertices[index++].set(rx, y, transparent, delta, delta * part); + smoothVertices[index++].set(lx, y, transparent, -delta, delta * part); + } + } else { + vertices[index++].set(rx, y, fillColor); + vertices[index++].set(lx, y, fillColor); + if (penWidth) { + vertices[index++].set(rx, y, borderColor); + vertices[index++].set(lx, y, borderColor); + vertices[index++].set(rX, Y, borderColor); + vertices[index++].set(lX, Y, borderColor); + } + } + } + Q_ASSERT(index == vertexCount); + + // Close the triangle strips. + if (m_antialiasing) { + indices[--innerAAHead] = indices[innerAATail - 1]; + indices[--innerAAHead] = indices[innerAATail - 2]; + Q_ASSERT(innerAATail <= indexCount); + } + if (penWidth) { + indices[--borderHead] = indices[borderTail - 1]; + indices[--borderHead] = indices[borderTail - 2]; + Q_ASSERT(borderTail <= indexCount); + } + if (m_antialiasing && penWidth) { + indices[--outerAAHead] = indices[outerAATail - 1]; + indices[--outerAAHead] = indices[outerAATail - 2]; + Q_ASSERT(outerAATail == indexCount); + } + } +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgbasicrectanglenode_p.h b/src/quick/scenegraph/qsgbasicrectanglenode_p.h new file mode 100644 index 0000000000..b1d1457590 --- /dev/null +++ b/src/quick/scenegraph/qsgbasicrectanglenode_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QSGBASICRECTANGLENODE_P_H +#define QSGBASICRECTANGLENODE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICK_PRIVATE_EXPORT QSGBasicRectangleNode : public QSGRectangleNode +{ +public: + QSGBasicRectangleNode(); + + void setRect(const QRectF &rect) override; + void setColor(const QColor &color) override; + void setPenColor(const QColor &color) override; + void setPenWidth(qreal width) override; + void setGradientStops(const QGradientStops &stops) override; + void setRadius(qreal radius) override; + void setAntialiasing(bool antialiasing) override; + void setAligned(bool aligned) override; + void update() override; + +protected: + virtual bool supportsAntialiasing() const { return true; } + virtual void updateMaterialAntialiasing() = 0; + virtual void updateMaterialBlending(QSGNode::DirtyState *state) = 0; + + void updateGeometry(); + void updateGradientTexture(); + + QRectF m_rect; + QGradientStops m_gradient_stops; + QColor m_color; + QColor m_border_color; + qreal m_radius; + qreal m_pen_width; + + uint m_aligned : 1; + uint m_antialiasing : 1; + uint m_gradient_is_opaque : 1; + uint m_dirty_geometry : 1; + + QSGGeometry m_geometry; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 2ba16e7328..b0dd24af23 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -38,27 +38,13 @@ ****************************************************************************/ #include <QtQuick/private/qsgcontext_p.h> -#include <QtQuick/private/qsgbatchrenderer_p.h> -#include <QtQuick/private/qsgdistancefieldutil_p.h> -#include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h> -#include <QtQuick/private/qsgdefaultrectanglenode_p.h> -#include <QtQuick/private/qsgdefaultimagenode_p.h> -#include <QtQuick/private/qsgdefaultpainternode_p.h> -#include <QtQuick/private/qsgdefaultglyphnode_p.h> -#include <QtQuick/private/qsgdistancefieldglyphnode_p.h> -#include <QtQuick/private/qsgdistancefieldglyphnode_p_p.h> -#include <QtQuick/private/qsgatlastexture_p.h> -#include <QtQuick/private/qsgrenderloop_p.h> -#include <QtQuick/private/qsgdefaultlayer_p.h> - #include <QtQuick/private/qsgtexture_p.h> #include <QtQuick/private/qquickpixmapcache_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> #include <QGuiApplication> #include <QScreen> -#include <QOpenGLContext> #include <QQuickWindow> -#include <QtGui/qopenglframebufferobject.h> #include <private/qqmlglobal_p.h> @@ -69,8 +55,6 @@ #include <private/qobject_p.h> #include <qmutex.h> -DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) - /* Comments about this class from Gunnar: @@ -114,28 +98,6 @@ Q_LOGGING_CATEGORY(QSG_LOG_TIME_GLYPH, "qt.scenegraph.time.glyph") // Timing inside the renderer base class Q_LOGGING_CATEGORY(QSG_LOG_TIME_RENDERER, "qt.scenegraph.time.renderer") -class QSGContextPrivate : public QObjectPrivate -{ -public: - QSGContextPrivate() - : antialiasingMethod(QSGContext::UndecidedAntialiasing) - , distanceFieldDisabled(qmlDisableDistanceField()) - , distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing) - , distanceFieldAntialiasingDecided(false) - { - } - - ~QSGContextPrivate() - { - } - - QMutex mutex; - QSGContext::AntialiasingMethod antialiasingMethod; - bool distanceFieldDisabled; - QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing; - bool distanceFieldAntialiasingDecided; -}; - bool qsg_useConsistentTiming() { int use = -1; @@ -274,20 +236,6 @@ public: QSGTexture *texture; }; -namespace QSGMultisampleAntialiasing { - class ImageNode : public QSGDefaultImageNode { - public: - void setAntialiasing(bool) { } - }; - - - class RectangleNode : public QSGDefaultRectangleNode { - public: - void setAntialiasing(bool) { } - }; -} - - /*! \class QSGContext @@ -300,92 +248,16 @@ namespace QSGMultisampleAntialiasing { */ QSGContext::QSGContext(QObject *parent) : - QObject(*(new QSGContextPrivate), parent) + QObject(parent) { - Q_D(QSGContext); - if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QSG_DISTANCEFIELD_ANTIALIASING"))) { - const QByteArray mode = qgetenv("QSG_DISTANCEFIELD_ANTIALIASING"); - d->distanceFieldAntialiasingDecided = true; - if (mode == "subpixel") - d->distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing; - else if (mode == "subpixel-lowq") - d->distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing; - else if (mode == "gray") - d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; - } - - // Adds compatibility with Qt 5.3 and earlier's QSG_RENDER_TIMING - if (qEnvironmentVariableIsSet("QSG_RENDER_TIMING")) { - const_cast<QLoggingCategory &>(QSG_LOG_TIME_GLYPH()).setEnabled(QtDebugMsg, true); - const_cast<QLoggingCategory &>(QSG_LOG_TIME_TEXTURE()).setEnabled(QtDebugMsg, true); - const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERER()).setEnabled(QtDebugMsg, true); - const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERLOOP()).setEnabled(QtDebugMsg, true); - const_cast<QLoggingCategory &>(QSG_LOG_TIME_COMPILATION()).setEnabled(QtDebugMsg, true); - } } - QSGContext::~QSGContext() { } -QSGRenderContext *QSGContext::createRenderContext() +void QSGContext::renderContextInitialized(QSGRenderContext *) { - return new QSGRenderContext(this); -} - -void QSGContext::renderContextInitialized(QSGRenderContext *renderContext) -{ - Q_D(QSGContext); - - d->mutex.lock(); - if (d->antialiasingMethod == UndecidedAntialiasing) { - if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_ANTIALIASING_METHOD"))) { - const QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD"); - if (aaType == "msaa") - d->antialiasingMethod = MsaaAntialiasing; - else if (aaType == "vertex") - d->antialiasingMethod = VertexAntialiasing; - } - if (d->antialiasingMethod == UndecidedAntialiasing) { - if (renderContext->openglContext()->format().samples() > 0) - d->antialiasingMethod = MsaaAntialiasing; - else - d->antialiasingMethod = VertexAntialiasing; - } - } - - // With OpenGL ES, except for Angle on Windows, use GrayAntialiasing, unless - // some value had been requested explicitly. This could not be decided - // before without a context. Now the context is ready. - if (!d->distanceFieldAntialiasingDecided) { - d->distanceFieldAntialiasingDecided = true; -#ifndef Q_OS_WIN32 - if (renderContext->openglContext()->isOpenGLES()) - d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; -#endif - } - - static bool dumped = false; - if (!dumped && QSG_LOG_INFO().isDebugEnabled()) { - dumped = true; - QSurfaceFormat format = renderContext->openglContext()->format(); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - qCDebug(QSG_LOG_INFO) << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize(); - qCDebug(QSG_LOG_INFO) << "Depth Buffer: " << format.depthBufferSize(); - qCDebug(QSG_LOG_INFO) << "Stencil Buffer: " << format.stencilBufferSize(); - qCDebug(QSG_LOG_INFO) << "Samples: " << format.samples(); - qCDebug(QSG_LOG_INFO) << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR); - qCDebug(QSG_LOG_INFO) << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER); - qCDebug(QSG_LOG_INFO) << "GL_VERSION: " << (const char *) funcs->glGetString(GL_VERSION); - QSet<QByteArray> exts = renderContext->openglContext()->extensions(); - QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e; - qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData(); - qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << renderContext->maxTextureSize(); - qCDebug(QSG_LOG_INFO) << "Debug context: " << format.testOption(QSurfaceFormat::DebugContext); - } - - d->mutex.unlock(); } void QSGContext::renderContextInvalidated(QSGRenderContext *) @@ -405,89 +277,16 @@ QSGRectangleNode *QSGContext::createRectangleNode(const QRectF &rect, const QCol return node; } -/*! - Factory function for scene graph backends of the Rectangle element. - */ -QSGRectangleNode *QSGContext::createRectangleNode() -{ - Q_D(QSGContext); - return d->antialiasingMethod == MsaaAntialiasing - ? new QSGMultisampleAntialiasing::RectangleNode - : new QSGDefaultRectangleNode; -} - -/*! - Factory function for scene graph backends of the Image element. - */ -QSGImageNode *QSGContext::createImageNode() -{ - Q_D(QSGContext); - return d->antialiasingMethod == MsaaAntialiasing - ? new QSGMultisampleAntialiasing::ImageNode - : new QSGDefaultImageNode; -} - -/*! - Factory function for scene graph backends of Painter elements - */ -QSGPainterNode *QSGContext::createPainterNode(QQuickPaintedItem *item) -{ - return new QSGDefaultPainterNode(item); -} /*! - Factory function for scene graph backends of the Text elements; - */ -QSGGlyphNode *QSGContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) -{ - Q_D(QSGContext); - - if (d->distanceFieldDisabled || preferNativeGlyphNode) { - return new QSGDefaultGlyphNode; - } else { - QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(rc); - node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing); - return node; - } -} - -/*! - * Factory function for scene graph backends of the QStyle stylable elements. Returns a - * null pointer if the backend doesn't provide its own node type. - */ -QSGNinePatchNode *QSGContext::createNinePatchNode() -{ - return 0; -} - -/*! - Factory function for scene graph backends of layers. + Creates a new animation driver. */ -QSGLayer *QSGContext::createLayer(QSGRenderContext *renderContext) -{ - return new QSGDefaultLayer(renderContext); -} -QSurfaceFormat QSGContext::defaultSurfaceFormat() const +QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent) { - QSurfaceFormat format = QSurfaceFormat::defaultFormat(); - static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); - static bool useStencil = qEnvironmentVariableIsEmpty("QSG_NO_STENCIL_BUFFER"); - static bool enableDebug = qEnvironmentVariableIsSet("QSG_OPENGL_DEBUG"); - format.setDepthBufferSize(useDepth ? 24 : 0); - format.setStencilBufferSize(useStencil ? 8 : 0); - if (enableDebug) - format.setOption(QSurfaceFormat::DebugContext); - if (QQuickWindow::hasDefaultAlphaBuffer()) - format.setAlphaBufferSize(8); - format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - return format; + return new QSGAnimationDriver(parent); } -/*! - Returns the minimum supported framebuffer object size. - */ - QSize QSGContext::minimumFBOSize() const { #ifdef Q_OS_MAC @@ -497,52 +296,26 @@ QSize QSGContext::minimumFBOSize() const return QSize(1, 1); } - - -/*! - Sets whether or not the scene graph should use the distance field technique to render text - */ -void QSGContext::setDistanceFieldEnabled(bool enabled) -{ - d_func()->distanceFieldDisabled = !enabled; -} - - -/*! - Returns true if the scene graph uses the distance field technique to render text - */ -bool QSGContext::isDistanceFieldEnabled() const +QSGRenderContext::QSGRenderContext(QSGContext *context) + : m_sg(context) + , m_distanceFieldCacheManager(0) { - return !d_func()->distanceFieldDisabled; } - - -/*! - Creates a new animation driver. - */ - -QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent) +QSGRenderContext::~QSGRenderContext() { - return new QSGAnimationDriver(parent); + invalidate(); } -QSGRenderContext::QSGRenderContext(QSGContext *context) - : m_gl(0) - , m_sg(context) - , m_atlasManager(0) - , m_depthStencilManager(0) - , m_distanceFieldCacheManager(0) - , m_maxTextureSize(0) - , m_brokenIBOs(false) - , m_serializedRender(false) - , m_attachToGLContext(true) +void QSGRenderContext::initialize(void *context) { + Q_UNUSED(context); } -QSGRenderContext::~QSGRenderContext() +void QSGRenderContext::invalidate() { - invalidate(); + m_sg->renderContextInvalidated(this); + emit invalidated(); } void QSGRenderContext::endSync() @@ -551,49 +324,14 @@ void QSGRenderContext::endSync() m_texturesToDelete.clear(); } -static QBasicMutex qsg_framerender_mutex; - -void QSGRenderContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId) -{ - if (m_serializedRender) - qsg_framerender_mutex.lock(); - - renderer->renderScene(fboId); - - if (m_serializedRender) - qsg_framerender_mutex.unlock(); - -} - /*! Factory function for scene graph backends of the distance-field glyph cache. */ -QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRawFont &font) -{ - if (!m_distanceFieldCacheManager) - m_distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager; - - QSGDistanceFieldGlyphCache *cache = m_distanceFieldCacheManager->cache(font); - if (!cache) { - cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font); - m_distanceFieldCacheManager->insertCache(font, cache); - } - - return cache; -} - -void QSGRenderContext::setAttachToGLContext(bool attach) +QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRawFont &) { - Q_ASSERT(!isValid()); - m_attachToGLContext = attach; + return nullptr; } -#define QSG_RENDERCONTEXT_PROPERTY "_q_sgrendercontext" - -QSGRenderContext *QSGRenderContext::from(QOpenGLContext *context) -{ - return qobject_cast<QSGRenderContext *>(context->property(QSG_RENDERCONTEXT_PROPERTY).value<QObject *>()); -} void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine) { @@ -602,178 +340,18 @@ void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine) } /*! - Initializes the scene graph render context with the GL context \a context. This also - emits the ready() signal so that the QML graph can start building scene graph nodes. - */ -void QSGRenderContext::initialize(QOpenGLContext *context) -{ - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); - - // Sanity check the surface format, in case it was overridden by the application - QSurfaceFormat requested = m_sg->defaultSurfaceFormat(); - QSurfaceFormat actual = context->format(); - if (requested.depthBufferSize() > 0 && actual.depthBufferSize() <= 0) - qWarning("QSGContext::initialize: depth buffer support missing, expect rendering errors"); - if (requested.stencilBufferSize() > 0 && actual.stencilBufferSize() <= 0) - qWarning("QSGContext::initialize: stencil buffer support missing, expect rendering errors"); - - if (!m_atlasManager) - m_atlasManager = new QSGAtlasTexture::Manager(); - - Q_ASSERT_X(!m_gl, "QSGRenderContext::initialize", "already initialized!"); - m_gl = context; - if (m_attachToGLContext) { - Q_ASSERT(!context->property(QSG_RENDERCONTEXT_PROPERTY).isValid()); - context->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant::fromValue(this)); - } - m_sg->renderContextInitialized(this); - -#ifdef Q_OS_LINUX - const char *vendor = (const char *) funcs->glGetString(GL_VENDOR); - if (strstr(vendor, "nouveau")) - m_brokenIBOs = true; - const char *renderer = (const char *) funcs->glGetString(GL_RENDERER); - if (strstr(renderer, "llvmpipe")) - m_serializedRender = true; - if (strstr(vendor, "Hisilicon Technologies") && strstr(renderer, "Immersion.16")) - m_brokenIBOs = true; -#endif - - emit initialized(); -} - -void QSGRenderContext::invalidate() -{ - if (!m_gl) - return; - - qDeleteAll(m_texturesToDelete); - m_texturesToDelete.clear(); - - qDeleteAll(m_textures); - m_textures.clear(); - - /* The cleanup of the atlas textures is a bit intriguing. - As part of the cleanup in the threaded render loop, we - do: - 1. call this function - 2. call QCoreApp::sendPostedEvents() to immediately process - any pending deferred deletes. - 3. delete the GL context. - - As textures need the atlas manager while cleaning up, the - manager needs to be cleaned up after the textures, so - we post a deleteLater here at the very bottom so it gets - deferred deleted last. - - Another alternative would be to use a QPointer in - QSGAtlasTexture::Texture, but this seemed simpler. - */ - m_atlasManager->invalidate(); - m_atlasManager->deleteLater(); - m_atlasManager = 0; - - // The following piece of code will read/write to the font engine's caches, - // potentially from different threads. However, this is safe because this - // code is only called from QQuickWindow's shutdown which is called - // only when the GUI is blocked, and multiple threads will call it in - // sequence. (see qsgdefaultglyphnode_p.cpp's init()) - for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(), - end = m_fontEnginesToClean.constEnd(); it != end; ++it) { - (*it)->clearGlyphCache(m_gl); - if (!(*it)->ref.deref()) - delete *it; - } - m_fontEnginesToClean.clear(); - - delete m_depthStencilManager; - m_depthStencilManager = 0; - - delete m_distanceFieldCacheManager; - m_distanceFieldCacheManager = 0; - - if (m_gl->property(QSG_RENDERCONTEXT_PROPERTY) == QVariant::fromValue(this)) - m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant()); - m_gl = 0; - - m_sg->renderContextInvalidated(this); - emit invalidated(); -} - -/*! - Returns a shared pointer to a depth stencil buffer that can be used with \a fbo. - */ -QSharedPointer<QSGDepthStencilBuffer> QSGRenderContext::depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo) -{ - if (!m_gl) - return QSharedPointer<QSGDepthStencilBuffer>(); - QSGDepthStencilBufferManager *manager = depthStencilBufferManager(); - QSGDepthStencilBuffer::Format format; - format.size = fbo->size(); - format.samples = fbo->format().samples(); - format.attachments = QSGDepthStencilBuffer::DepthAttachment | QSGDepthStencilBuffer::StencilAttachment; - QSharedPointer<QSGDepthStencilBuffer> buffer = manager->bufferForFormat(format); - if (buffer.isNull()) { - buffer = QSharedPointer<QSGDepthStencilBuffer>(new QSGDefaultDepthStencilBuffer(m_gl, format)); - manager->insertBuffer(buffer); - } - return buffer; -} - -/*! - Returns a pointer to the context's depth/stencil buffer manager. This is useful for custom - implementations of \l depthStencilBufferForFbo(). - */ -QSGDepthStencilBufferManager *QSGRenderContext::depthStencilBufferManager() -{ - if (!m_gl) - return 0; - if (!m_depthStencilManager) - m_depthStencilManager = new QSGDepthStencilBufferManager(m_gl); - return m_depthStencilManager; -} - - -/*! Factory function for texture objects. If \a image is a valid image, the QSGTexture::setImage function will be called with \a image as argument. */ -QSGTexture *QSGRenderContext::createTexture(const QImage &image, uint flags) const -{ - bool atlas = flags & CreateTexture_Atlas; - bool mipmap = flags & CreateTexture_Mipmap; - bool alpha = flags & CreateTexture_Alpha; - - // The atlas implementation is only supported from the render thread and - // does not support mipmaps. - if (!mipmap && atlas && openglContext() && QThread::currentThread() == openglContext()->thread()) { - QSGTexture *t = m_atlasManager->create(image, alpha); - if (t) - return t; - } - - QSGPlainTexture *texture = new QSGPlainTexture(); - texture->setImage(image); - if (texture->hasAlphaChannel() && !alpha) - texture->setHasAlphaChannel(false); - - return texture; -} - /*! Factory function for the scene graph renderers. The renderers are used for the toplevel renderer and once for every QQuickShaderEffectSource used in the QML scene. */ -QSGRenderer *QSGRenderContext::createRenderer() -{ - return new QSGBatchRenderer::Renderer(this); -} QSGTexture *QSGRenderContext::textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window) { @@ -803,41 +381,6 @@ void QSGRenderContext::textureFactoryDestroyed(QObject *o) m_mutex.unlock(); } -/*! - Compile \a shader, optionally using \a vertexCode and \a fragmentCode as - replacement for the source code supplied by \a shader. - - If \a vertexCode or \a fragmentCode is supplied, the caller is responsible - for setting up attribute bindings. - - \a material is supplied in case the implementation needs to take the - material flags into account. - */ - -void QSGRenderContext::compile(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode, const char *fragmentCode) -{ - Q_UNUSED(material); - if (vertexCode || fragmentCode) { - Q_ASSERT_X((material->flags() & QSGMaterial::CustomCompileStep) == 0, - "QSGRenderContext::compile()", - "materials with custom compile step cannot have custom vertex/fragment code"); - QOpenGLShaderProgram *p = shader->program(); - p->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader()); - p->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader()); - p->link(); - if (!p->isLinked()) - qWarning() << "shader compilation failed:" << endl << p->log(); - } else { - shader->compile(); - } -} - -void QSGRenderContext::initialize(QSGMaterialShader *shader) -{ - shader->program()->bind(); - shader->initialize(); -} - #include "qsgcontext.moc" QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 38d0cdaccc..3893560142 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -53,6 +53,7 @@ #include <QtCore/QObject> #include <QtCore/qabstractanimation.h> +#include <QtCore/QMutex> #include <QtGui/QImage> #include <QtGui/QSurfaceFormat> @@ -61,14 +62,9 @@ #include <private/qrawfont_p.h> #include <QtQuick/qsgnode.h> -#include <QtQuick/private/qsgdepthstencilbuffer_p.h> QT_BEGIN_NAMESPACE -namespace QSGAtlasTexture { - class Manager; -} - class QSGContextPrivate; class QSGRectangleNode; class QSGImageNode; @@ -80,13 +76,8 @@ class QSGDistanceFieldGlyphCache; class QQuickWindow; class QSGTexture; class QSGMaterial; -class QSGMaterialShader; class QSGRenderLoop; class QSGLayer; - -class QOpenGLContext; -class QOpenGLFramebufferObject; - class QQuickTextureFactory; class QSGDistanceFieldGlyphCacheManager; class QSGContext; @@ -112,39 +103,24 @@ public: }; QSGRenderContext(QSGContext *context); - ~QSGRenderContext(); + virtual ~QSGRenderContext(); - QOpenGLContext *openglContext() const { return m_gl; } QSGContext *sceneGraphContext() const { return m_sg; } - virtual bool isValid() const { return m_gl; } + virtual bool isValid() const { return true; } - virtual void initialize(QOpenGLContext *context); + virtual void initialize(void *context); virtual void invalidate(); - - virtual void renderNextFrame(QSGRenderer *renderer, GLuint fboId); + virtual void renderNextFrame(QSGRenderer *renderer, uint fboId) = 0; virtual void endSync(); - virtual QSharedPointer<QSGDepthStencilBuffer> depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo); - QSGDepthStencilBufferManager *depthStencilBufferManager(); - virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font); QSGTexture *textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window); - virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const; - - virtual QSGRenderer *createRenderer(); + virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const = 0; + virtual QSGRenderer *createRenderer() = 0; - virtual void compile(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0); - virtual void initialize(QSGMaterialShader *shader); - - void setAttachToGLContext(bool attach); void registerFontengineForCleanup(QFontEngine *engine); - static QSGRenderContext *from(QOpenGLContext *context); - - bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; } - int maxTextureSize() const { return m_maxTextureSize; } - Q_SIGNALS: void initialized(); void invalidated(); @@ -153,29 +129,20 @@ public Q_SLOTS: void textureFactoryDestroyed(QObject *o); protected: - QOpenGLContext *m_gl; QSGContext *m_sg; QMutex m_mutex; QHash<QQuickTextureFactory *, QSGTexture *> m_textures; QSet<QSGTexture *> m_texturesToDelete; - QSGAtlasTexture::Manager *m_atlasManager; - - QSGDepthStencilBufferManager *m_depthStencilManager; QSGDistanceFieldGlyphCacheManager *m_distanceFieldCacheManager; QSet<QFontEngine *> m_fontEnginesToClean; - int m_maxTextureSize; - bool m_brokenIBOs; - bool m_serializedRender; - bool m_attachToGLContext; }; class Q_QUICK_PRIVATE_EXPORT QSGContext : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QSGContext) public: enum AntialiasingMethod { @@ -185,26 +152,23 @@ public: }; explicit QSGContext(QObject *parent = 0); - ~QSGContext(); + virtual ~QSGContext(); virtual void renderContextInitialized(QSGRenderContext *renderContext); virtual void renderContextInvalidated(QSGRenderContext *renderContext); - virtual QSGRenderContext *createRenderContext(); + virtual QSGRenderContext *createRenderContext() = 0; QSGRectangleNode *createRectangleNode(const QRectF &rect, const QColor &c); - virtual QSGRectangleNode *createRectangleNode(); - virtual QSGImageNode *createImageNode(); - virtual QSGPainterNode *createPainterNode(QQuickPaintedItem *item); - virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode); - virtual QSGNinePatchNode *createNinePatchNode(); - virtual QSGLayer *createLayer(QSGRenderContext *renderContext); + virtual QSGRectangleNode *createRectangleNode() = 0; + virtual QSGImageNode *createImageNode() = 0; + virtual QSGPainterNode *createPainterNode(QQuickPaintedItem *item) = 0; + virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) = 0; + virtual QSGNinePatchNode *createNinePatchNode() = 0; + virtual QSGLayer *createLayer(QSGRenderContext *renderContext) = 0; virtual QAnimationDriver *createAnimationDriver(QObject *parent); virtual QSize minimumFBOSize() const; - virtual QSurfaceFormat defaultSurfaceFormat() const; - - void setDistanceFieldEnabled(bool enabled); - bool isDistanceFieldEnabled() const; + virtual QSurfaceFormat defaultSurfaceFormat() const = 0; static QSGContext *createDefaultContext(); static QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image); diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index f5c2b6880b..1605212c76 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -43,8 +43,19 @@ #include <QtCore/private/qfactoryloader_p.h> #include <QtCore/qlibraryinfo.h> +// Built-in adaptations +#include <QtQuick/private/qsgsoftwareadaptation_p.h> +#ifdef QSG_D3D12 +#include <QtQuick/private/qsgd3d12adaptation_p.h> +#endif +#ifndef QT_NO_OPENGL +#include <QtQuick/private/qsgdefaultcontext_p.h> +#endif + QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_INFO) + QSGContextPlugin::QSGContextPlugin(QObject *parent) : QObject(parent) { @@ -59,61 +70,97 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QSGContextFactoryInterface_iid, QLatin1String("/scenegraph"))) #endif -struct QSGAdaptionPluginData +struct QSGAdaptionBackendData { - QSGAdaptionPluginData() - : tried(false) - , factory(0) - { - } - - ~QSGAdaptionPluginData() - { - } + QSGAdaptionBackendData(); bool tried; QSGContextFactoryInterface *factory; - QString deviceName; + QString name; + + QVector<QSGContextFactoryInterface *> builtIns; }; -Q_GLOBAL_STATIC(QSGAdaptionPluginData, qsg_adaptation_data) +QSGAdaptionBackendData::QSGAdaptionBackendData() + : tried(false) + , factory(0) +{ + // Fill in the table with the built-in adaptations. + builtIns.append(new QSGSoftwareAdaptation); +#ifdef QSG_D3D12 + builtIns.append(new QSGD3D12Adaptation); +#endif +} -QSGAdaptionPluginData *contextFactory() +Q_GLOBAL_STATIC(QSGAdaptionBackendData, qsg_adaptation_data) + +QSGAdaptionBackendData *contextFactory() { - QSGAdaptionPluginData *plugin = qsg_adaptation_data(); - if (!plugin->tried) { + QSGAdaptionBackendData *backendData = qsg_adaptation_data(); + + if (!backendData->tried) { + backendData->tried = true; - plugin->tried = true; const QStringList args = QGuiApplication::arguments(); - QString device; + QString requestedBackend; + for (int index = 0; index < args.count(); ++index) { if (args.at(index).startsWith(QLatin1String("--device="))) { - device = args.at(index).mid(9); + requestedBackend = args.at(index).mid(9); break; } } - if (device.isEmpty()) - device = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE")); -#ifndef QT_NO_LIBRARY - if (!device.isEmpty()) { - const int index = loader()->indexOf(device); - if (index != -1) - plugin->factory = qobject_cast<QSGContextFactoryInterface*>(loader()->instance(index)); - plugin->deviceName = device; + if (requestedBackend.isEmpty() && qEnvironmentVariableIsSet("QMLSCENE_DEVICE")) + requestedBackend = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE")); + + // A modern alternative. Scenegraph adaptations can represent backends + // for different graphics APIs as well, instead of being specific to + // some device or platform. + if (requestedBackend.isEmpty() && qEnvironmentVariableIsSet("QT_QUICK_BACKEND")) + requestedBackend = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND")); + +#ifdef QT_NO_OPENGL + // If this is a build without OpenGL, and no backend has been set + // default to the software renderer + if (requestedBackend.isEmpty()) + requestedBackend = QString::fromLocal8Bit("software"); +#endif + + if (!requestedBackend.isEmpty()) { #ifndef QT_NO_DEBUG - if (!plugin->factory) { - qWarning("Could not create scene graph context for device '%s'" - " - check that plugins are installed correctly in %s", - qPrintable(device), - qPrintable(QLibraryInfo::location(QLibraryInfo::PluginsPath))); - } + qCDebug(QSG_LOG_INFO) << "Loading backend" << requestedBackend; #endif - } + // First look for a built-in adaptation. + for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) { + if (builtInBackend->keys().contains(requestedBackend)) { + backendData->factory = builtInBackend; + break; + } + } + + // Then try the plugins. + if (!backendData->factory) { +#ifndef QT_NO_LIBRARY + const int index = loader()->indexOf(requestedBackend); + if (index != -1) + backendData->factory = qobject_cast<QSGContextFactoryInterface*>(loader()->instance(index)); + backendData->name = requestedBackend; +#ifndef QT_NO_DEBUG + if (!backendData->factory) { + qWarning("Could not create scene graph context for backend '%s'" + " - check that plugins are installed correctly in %s", + qPrintable(requestedBackend), + qPrintable(QLibraryInfo::location(QLibraryInfo::PluginsPath))); + } +#endif + } #endif // QT_NO_LIBRARY + } } - return plugin; + + return backendData; } @@ -126,10 +173,14 @@ QSGAdaptionPluginData *contextFactory() */ QSGContext *QSGContext::createDefaultContext() { - QSGAdaptionPluginData *plugin = contextFactory(); - if (plugin->factory) - return plugin->factory->create(plugin->deviceName); - return new QSGContext(); + QSGAdaptionBackendData *backendData = contextFactory(); + if (backendData->factory) + return backendData->factory->create(backendData->name); +#ifndef QT_NO_OPENGL + return new QSGDefaultContext(); +#else + return nullptr; +#endif } @@ -143,9 +194,9 @@ QSGContext *QSGContext::createDefaultContext() QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &image) { - QSGAdaptionPluginData *plugin = contextFactory(); - if (plugin->factory) - return plugin->factory->createTextureFactoryFromImage(image); + QSGAdaptionBackendData *backendData = contextFactory(); + if (backendData->factory) + return backendData->factory->createTextureFactoryFromImage(image); return 0; } @@ -157,14 +208,10 @@ QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &im QSGRenderLoop *QSGContext::createWindowManager() { - QSGAdaptionPluginData *plugin = contextFactory(); - if (plugin->factory) - return plugin->factory->createWindowManager(); + QSGAdaptionBackendData *backendData = contextFactory(); + if (backendData->factory) + return backendData->factory->createWindowManager(); return 0; } - - - - QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp new file mode 100644 index 0000000000..f969359e7c --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultcontext.cpp @@ -0,0 +1,243 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgdefaultcontext_p.h" + +#include <QtQuick/private/qsgdistancefieldutil_p.h> +#include <QtQuick/private/qsgdefaultrectanglenode_p.h> +#include <QtQuick/private/qsgdefaultimagenode_p.h> +#include <QtQuick/private/qsgdefaultpainternode_p.h> +#include <QtQuick/private/qsgdefaultglyphnode_p.h> +#include <QtQuick/private/qsgdistancefieldglyphnode_p.h> +#include <QtQuick/private/qsgdistancefieldglyphnode_p_p.h> +#include <QtQuick/private/qsgrenderloop_p.h> +#include <QtQuick/private/qsgdefaultlayer_p.h> +#include <QtQuick/private/qsgdefaultrendercontext_p.h> + +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFramebufferObject> + +#include <QtQuick/QQuickWindow> + +#include <private/qqmlglobal_p.h> + +QT_BEGIN_NAMESPACE + +namespace QSGMultisampleAntialiasing { + class ImageNode : public QSGDefaultImageNode { + public: + void setAntialiasing(bool) { } + }; + + + class RectangleNode : public QSGDefaultRectangleNode { + public: + void setAntialiasing(bool) { } + }; +} + +DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) + +QSGDefaultContext::QSGDefaultContext(QObject *parent) + : QSGContext (parent) + , m_antialiasingMethod(QSGContext::UndecidedAntialiasing) + , m_distanceFieldDisabled(qmlDisableDistanceField()) + , m_distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing) + , m_distanceFieldAntialiasingDecided(false) +{ + if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QSG_DISTANCEFIELD_ANTIALIASING"))) { + const QByteArray mode = qgetenv("QSG_DISTANCEFIELD_ANTIALIASING"); + m_distanceFieldAntialiasingDecided = true; + if (mode == "subpixel") + m_distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing; + else if (mode == "subpixel-lowq") + m_distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing; + else if (mode == "gray") + m_distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; + } + + // Adds compatibility with Qt 5.3 and earlier's QSG_RENDER_TIMING + if (qEnvironmentVariableIsSet("QSG_RENDER_TIMING")) { + const_cast<QLoggingCategory &>(QSG_LOG_TIME_GLYPH()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(QSG_LOG_TIME_TEXTURE()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERER()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERLOOP()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(QSG_LOG_TIME_COMPILATION()).setEnabled(QtDebugMsg, true); + } +} + +QSGDefaultContext::~QSGDefaultContext() +{ + +} + +void QSGDefaultContext::renderContextInitialized(QSGRenderContext *renderContext) +{ + m_mutex.lock(); + + auto openglRenderContext = static_cast<const QSGDefaultRenderContext *>(renderContext); + if (m_antialiasingMethod == UndecidedAntialiasing) { + if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_ANTIALIASING_METHOD"))) { + const QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD"); + if (aaType == "msaa") + m_antialiasingMethod = MsaaAntialiasing; + else if (aaType == "vertex") + m_antialiasingMethod = VertexAntialiasing; + } + if (m_antialiasingMethod == UndecidedAntialiasing) { + if (openglRenderContext->openglContext()->format().samples() > 0) + m_antialiasingMethod = MsaaAntialiasing; + else + m_antialiasingMethod = VertexAntialiasing; + } + } + + // With OpenGL ES, except for Angle on Windows, use GrayAntialiasing, unless + // some value had been requested explicitly. This could not be decided + // before without a context. Now the context is ready. + if (!m_distanceFieldAntialiasingDecided) { + m_distanceFieldAntialiasingDecided = true; +#ifndef Q_OS_WIN32 + if (openglRenderContext->openglContext()->isOpenGLES()) + m_distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; +#endif + } + + static bool dumped = false; + if (!dumped && QSG_LOG_INFO().isDebugEnabled()) { + dumped = true; + QSurfaceFormat format = openglRenderContext->openglContext()->format(); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + qCDebug(QSG_LOG_INFO) << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize(); + qCDebug(QSG_LOG_INFO) << "Depth Buffer: " << format.depthBufferSize(); + qCDebug(QSG_LOG_INFO) << "Stencil Buffer: " << format.stencilBufferSize(); + qCDebug(QSG_LOG_INFO) << "Samples: " << format.samples(); + qCDebug(QSG_LOG_INFO) << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR); + qCDebug(QSG_LOG_INFO) << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER); + qCDebug(QSG_LOG_INFO) << "GL_VERSION: " << (const char *) funcs->glGetString(GL_VERSION); + QSet<QByteArray> exts = openglRenderContext->openglContext()->extensions(); + QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e; + qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData(); + qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << openglRenderContext->maxTextureSize(); + qCDebug(QSG_LOG_INFO) << "Debug context: " << format.testOption(QSurfaceFormat::DebugContext); + } + + m_mutex.unlock(); +} + +void QSGDefaultContext::renderContextInvalidated(QSGRenderContext *) +{ +} + +QSGRenderContext *QSGDefaultContext::createRenderContext() +{ + return new QSGDefaultRenderContext(this); +} + +QSGRectangleNode *QSGDefaultContext::createRectangleNode() +{ + return m_antialiasingMethod == MsaaAntialiasing + ? new QSGMultisampleAntialiasing::RectangleNode + : new QSGDefaultRectangleNode; +} + +QSGImageNode *QSGDefaultContext::createImageNode() +{ + return m_antialiasingMethod == MsaaAntialiasing + ? new QSGMultisampleAntialiasing::ImageNode + : new QSGDefaultImageNode; +} + +QSGPainterNode *QSGDefaultContext::createPainterNode(QQuickPaintedItem *item) +{ + return new QSGDefaultPainterNode(item); +} + +QSGGlyphNode *QSGDefaultContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) +{ + if (m_distanceFieldDisabled || preferNativeGlyphNode) { + return new QSGDefaultGlyphNode; + } else { + QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(rc); + node->setPreferredAntialiasingMode(m_distanceFieldAntialiasing); + return node; + } +} + +/*! + * Factory function for scene graph backends of the QStyle stylable elements. Returns a + * null pointer if the backend doesn't provide its own node type. + */ +QSGNinePatchNode *QSGDefaultContext::createNinePatchNode() +{ + return nullptr; +} + +QSGLayer *QSGDefaultContext::createLayer(QSGRenderContext *renderContext) +{ + return new QSGDefaultLayer(renderContext); +} + +QSurfaceFormat QSGDefaultContext::defaultSurfaceFormat() const +{ + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); + static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); + static bool useStencil = qEnvironmentVariableIsEmpty("QSG_NO_STENCIL_BUFFER"); + static bool enableDebug = qEnvironmentVariableIsSet("QSG_OPENGL_DEBUG"); + format.setDepthBufferSize(useDepth ? 24 : 0); + format.setStencilBufferSize(useStencil ? 8 : 0); + if (enableDebug) + format.setOption(QSurfaceFormat::DebugContext); + if (QQuickWindow::hasDefaultAlphaBuffer()) + format.setAlphaBufferSize(8); + format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); + return format; +} + +void QSGDefaultContext::setDistanceFieldEnabled(bool enabled) +{ + m_distanceFieldDisabled = !enabled; +} + +bool QSGDefaultContext::isDistanceFieldEnabled() const +{ + return !m_distanceFieldDisabled; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultcontext_p.h b/src/quick/scenegraph/qsgdefaultcontext_p.h new file mode 100644 index 0000000000..0569b7c321 --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultcontext_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGDEFAULTCONTEXT_H +#define QSGDEFAULTCONTEXT_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qsgcontext_p.h> +#include <QtQuick/private/qsgdistancefieldglyphnode_p.h> + +QT_BEGIN_NAMESPACE + +class QSGDefaultContext : public QSGContext +{ +public: + QSGDefaultContext(QObject *parent = 0); + ~QSGDefaultContext(); + + void renderContextInitialized(QSGRenderContext *renderContext) override; + void renderContextInvalidated(QSGRenderContext *) override; + QSGRenderContext *createRenderContext() override; + QSGRectangleNode *createRectangleNode() override; + QSGImageNode *createImageNode() override; + QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override; + QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override; + QSGNinePatchNode *createNinePatchNode() override; + QSGLayer *createLayer(QSGRenderContext *renderContext) override; + QSurfaceFormat defaultSurfaceFormat() const override; + + void setDistanceFieldEnabled(bool enabled); + bool isDistanceFieldEnabled() const; + +private: + QMutex m_mutex; + QSGContext::AntialiasingMethod m_antialiasingMethod; + bool m_distanceFieldDisabled; + QSGDistanceFieldGlyphNode::AntialiasingMode m_distanceFieldAntialiasing; + bool m_distanceFieldAntialiasingDecided; +}; + +QT_END_NAMESPACE + +#endif // QSGDEFAULTCONTEXT_H diff --git a/src/quick/scenegraph/qsgdefaultglyphnode.cpp b/src/quick/scenegraph/qsgdefaultglyphnode.cpp index 082a4f8c09..b856d99bc1 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode.cpp @@ -40,59 +40,11 @@ #include "qsgdefaultglyphnode_p.h" #include "qsgdefaultglyphnode_p_p.h" -#include <qopenglshaderprogram.h> -#include <private/qfont_p.h> - QT_BEGIN_NAMESPACE -QSGDefaultGlyphNode::QSGDefaultGlyphNode() - : m_style(QQuickText::Normal) - , m_material(0) - , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) -{ - m_geometry.setDrawingMode(GL_TRIANGLES); - setGeometry(&m_geometry); -} - -QSGDefaultGlyphNode::~QSGDefaultGlyphNode() -{ - delete m_material; -} - -void QSGDefaultGlyphNode::setColor(const QColor &color) -{ - m_color = color; - if (m_material != 0) { - m_material->setColor(color); - markDirty(DirtyMaterial); - } -} - -void QSGDefaultGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs) -{ - if (m_material != 0) - delete m_material; - - m_position = position; - m_glyphs = glyphs; - -#ifdef QSG_RUNTIME_DESCRIPTION - qsgnode_set_description(this, QLatin1String("glyphs")); -#endif -} - -void QSGDefaultGlyphNode::setStyle(QQuickText::TextStyle style) -{ - if (m_style == style) - return; - m_style = style; -} - -void QSGDefaultGlyphNode::setStyleColor(const QColor &color) +void QSGDefaultGlyphNode::setMaterialColor(const QColor &color) { - if (m_styleColor == color) - return; - m_styleColor = color; + static_cast<QSGTextMaskMaterial *>(m_material)->setColor(color); } void QSGDefaultGlyphNode::update() @@ -120,11 +72,12 @@ void QSGDefaultGlyphNode::update() m_material = material; } - m_material->setColor(m_color); + QSGTextMaskMaterial *textMaskMaterial = static_cast<QSGTextMaskMaterial *>(m_material); + textMaskMaterial->setColor(m_color); QRectF boundingRect; - m_material->populate(m_position, m_glyphs.glyphIndexes(), m_glyphs.positions(), geometry(), - &boundingRect, &m_baseLine, margins); + textMaskMaterial->populate(m_position, m_glyphs.glyphIndexes(), m_glyphs.positions(), geometry(), + &boundingRect, &m_baseLine, margins); setBoundingRect(boundingRect); setMaterial(m_material); diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 3da7a10456..7c2663d5a3 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -49,6 +49,7 @@ #include <QtQuick/qquickwindow.h> #include <QtQuick/private/qsgtexture_p.h> +#include <QtQuick/private/qsgdefaultrendercontext_p.h> #include <private/qrawfont_p.h> #include <QtCore/qmath.h> @@ -427,7 +428,7 @@ void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat) if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) { m_glyphCache = new QOpenGLTextureGlyphCache(glyphFormat, glyphCacheTransform); fontEngine->setGlyphCache(ctx, m_glyphCache.data()); - QSGRenderContext *sg = QSGRenderContext::from(ctx); + auto sg = QSGDefaultRenderContext::from(ctx); Q_ASSERT(sg); sg->registerFontengineForCleanup(fontEngine); } diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p.h index 4efeaea373..0eb7a4e4bd 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.h +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.h @@ -52,39 +52,15 @@ // #include <private/qsgadaptationlayer_p.h> -#include <QtQuick/qsgnode.h> +#include <private/qsgbasicglyphnode_p.h> QT_BEGIN_NAMESPACE -class QGlyphs; -class QSGTextMaskMaterial; -class QSGDefaultGlyphNode: public QSGGlyphNode +class QSGDefaultGlyphNode : public QSGBasicGlyphNode { public: - QSGDefaultGlyphNode(); - virtual ~QSGDefaultGlyphNode(); - - virtual QPointF baseLine() const { return m_baseLine; } - virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs); - virtual void setColor(const QColor &color); - - virtual void setPreferredAntialiasingMode(AntialiasingMode) { } - virtual void setStyle(QQuickText::TextStyle); - virtual void setStyleColor(const QColor &); - - virtual void update(); - -protected: - QGlyphRun m_glyphs; - QPointF m_position; - QColor m_color; - QQuickText::TextStyle m_style; - QColor m_styleColor; - - QPointF m_baseLine; - QSGTextMaskMaterial *m_material; - - QSGGeometry m_geometry; + void setMaterialColor(const QColor &color) override; + void update() override; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultimagenode.cpp b/src/quick/scenegraph/qsgdefaultimagenode.cpp index bb4db150c0..9fed70a7de 100644 --- a/src/quick/scenegraph/qsgdefaultimagenode.cpp +++ b/src/quick/scenegraph/qsgdefaultimagenode.cpp @@ -39,38 +39,12 @@ #include "qsgdefaultimagenode_p.h" #include <private/qsgmaterialshader_p.h> - -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qmath.h> -#include <QtGui/qopenglfunctions.h> - -#include <qsgtexturematerial.h> #include <private/qsgtexturematerial_p.h> -#include <qsgmaterial.h> +#include <QtGui/qopenglfunctions.h> +#include <QtCore/qmath.h> QT_BEGIN_NAMESPACE -namespace -{ - struct SmoothVertex - { - float x, y, u, v; - float dx, dy, du, dv; - }; - - const QSGGeometry::AttributeSet &smoothAttributeSet() - { - static QSGGeometry::Attribute data[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), - QSGGeometry::Attribute::create(1, 2, GL_FLOAT, false), - QSGGeometry::Attribute::create(2, 2, GL_FLOAT, false), - QSGGeometry::Attribute::create(3, 2, GL_FLOAT, false) - }; - static QSGGeometry::AttributeSet attrs = { 4, sizeof(SmoothVertex), data }; - return attrs; - } -} - class SmoothTextureMaterialShader : public QSGTextureMaterialShader { public: @@ -144,52 +118,9 @@ void SmoothTextureMaterialShader::initialize() } QSGDefaultImageNode::QSGDefaultImageNode() - : m_innerSourceRect(0, 0, 1, 1) - , m_subSourceRect(0, 0, 1, 1) - , m_antialiasing(false) - , m_mirror(false) - , m_dirtyGeometry(false) - , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) { setMaterial(&m_materialO); setOpaqueMaterial(&m_material); - setGeometry(&m_geometry); - -#ifdef QSG_RUNTIME_DESCRIPTION - qsgnode_set_description(this, QLatin1String("image")); -#endif -} - -void QSGDefaultImageNode::setTargetRect(const QRectF &rect) -{ - if (rect == m_targetRect) - return; - m_targetRect = rect; - m_dirtyGeometry = true; -} - -void QSGDefaultImageNode::setInnerTargetRect(const QRectF &rect) -{ - if (rect == m_innerTargetRect) - return; - m_innerTargetRect = rect; - m_dirtyGeometry = true; -} - -void QSGDefaultImageNode::setInnerSourceRect(const QRectF &rect) -{ - if (rect == m_innerSourceRect) - return; - m_innerSourceRect = rect; - m_dirtyGeometry = true; -} - -void QSGDefaultImageNode::setSubSourceRect(const QRectF &rect) -{ - if (rect == m_subSourceRect) - return; - m_subSourceRect = rect; - m_dirtyGeometry = true; } void QSGDefaultImageNode::setFiltering(QSGTexture::Filtering filtering) @@ -203,7 +134,6 @@ void QSGDefaultImageNode::setFiltering(QSGTexture::Filtering filtering) markDirty(DirtyMaterial); } - void QSGDefaultImageNode::setMipmapFiltering(QSGTexture::Filtering filtering) { if (m_material.mipmapFiltering() == filtering) @@ -237,73 +167,37 @@ void QSGDefaultImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) markDirty(DirtyMaterial); } - -void QSGDefaultImageNode::setTexture(QSGTexture *texture) -{ - Q_ASSERT(texture); - - m_material.setTexture(texture); - m_materialO.setTexture(texture); - m_smoothMaterial.setTexture(texture); - m_material.setFlag(QSGMaterial::Blending, texture->hasAlphaChannel()); - - markDirty(DirtyMaterial); - - // Because the texture can be a different part of the atlas, we need to update it... - m_dirtyGeometry = true; -} - -void QSGDefaultImageNode::setAntialiasing(bool antialiasing) +void QSGDefaultImageNode::updateMaterialAntialiasing() { - if (antialiasing == m_antialiasing) - return; - m_antialiasing = antialiasing; if (m_antialiasing) { setMaterial(&m_smoothMaterial); setOpaqueMaterial(0); - setGeometry(new QSGGeometry(smoothAttributeSet(), 0)); - setFlag(OwnsGeometry, true); } else { setMaterial(&m_materialO); setOpaqueMaterial(&m_material); - setGeometry(&m_geometry); - setFlag(OwnsGeometry, false); } - m_dirtyGeometry = true; } -void QSGDefaultImageNode::setMirror(bool mirror) +void QSGDefaultImageNode::setMaterialTexture(QSGTexture *texture) { - if (mirror == m_mirror) - return; - m_mirror = mirror; - m_dirtyGeometry = true; + m_material.setTexture(texture); + m_materialO.setTexture(texture); + m_smoothMaterial.setTexture(texture); } - -void QSGDefaultImageNode::update() +QSGTexture *QSGDefaultImageNode::materialTexture() const { - if (m_dirtyGeometry) - updateGeometry(); + return m_material.texture(); } -void QSGDefaultImageNode::preprocess() +bool QSGDefaultImageNode::updateMaterialBlending() { - bool doDirty = false; - QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(m_material.texture()); - if (t) { - doDirty = t->updateTexture(); - if (doDirty) - updateGeometry(); - } - bool alpha = m_material.flags() & QSGMaterial::Blending; - if (m_material.texture() && alpha != m_material.texture()->hasAlphaChannel()) { + const bool alpha = m_material.flags() & QSGMaterial::Blending; + if (materialTexture() && alpha != materialTexture()->hasAlphaChannel()) { m_material.setFlag(QSGMaterial::Blending, !alpha); - doDirty = true; + return true; } - - if (doDirty) - markDirty(DirtyMaterial); + return false; } inline static bool isPowerOfTwo(int x) @@ -312,360 +206,21 @@ inline static bool isPowerOfTwo(int x) return x == (x & -x); } -namespace { - struct X { float x, tx; }; - struct Y { float y, ty; }; -} - -static inline void appendQuad(quint16 **indices, quint16 topLeft, quint16 topRight, - quint16 bottomLeft, quint16 bottomRight) -{ - *(*indices)++ = topLeft; - *(*indices)++ = bottomLeft; - *(*indices)++ = bottomRight; - *(*indices)++ = bottomRight; - *(*indices)++ = topRight; - *(*indices)++ = topLeft; -} - -void QSGDefaultImageNode::updateGeometry() +bool QSGDefaultImageNode::supportsWrap(const QSize &size) const { - Q_ASSERT(!m_targetRect.isEmpty()); - const QSGTexture *t = m_material.texture(); - if (!t) { - QSGGeometry *g = geometry(); - g->allocate(4); - g->setDrawingMode(GL_TRIANGLE_STRIP); - memset(g->vertexData(), 0, g->sizeOfVertex() * 4); - } else { - QRectF sourceRect = t->normalizedTextureSubRect(); - - QRectF innerSourceRect(sourceRect.x() + m_innerSourceRect.x() * sourceRect.width(), - sourceRect.y() + m_innerSourceRect.y() * sourceRect.height(), - m_innerSourceRect.width() * sourceRect.width(), - m_innerSourceRect.height() * sourceRect.height()); - - bool hasMargins = m_targetRect != m_innerTargetRect; - - int floorLeft = qFloor(m_subSourceRect.left()); - int ceilRight = qCeil(m_subSourceRect.right()); - int floorTop = qFloor(m_subSourceRect.top()); - int ceilBottom = qCeil(m_subSourceRect.bottom()); - int hTiles = ceilRight - floorLeft; - int vTiles = ceilBottom - floorTop; + bool wrapSupported = true; - bool hasTiles = hTiles != 1 || vTiles != 1; - bool fullTexture = innerSourceRect == QRectF(0, 0, 1, 1); - - bool wrapSupported = true; - - QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLContext *ctx = QOpenGLContext::currentContext(); #ifndef QT_OPENGL_ES_2 - if (ctx->isOpenGLES()) + if (ctx->isOpenGLES()) #endif - { - bool npotSupported = ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat); - QSize size = t->textureSize(); - const bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); - wrapSupported = npotSupported || !isNpot; - } - - // An image can be rendered as a single quad if: - // - There are no margins, and either: - // - the image isn't repeated - // - the source rectangle fills the entire texture so that texture wrapping can be used, - // and NPOT is supported - if (!hasMargins && (!hasTiles || (fullTexture && wrapSupported))) { - QRectF sr; - if (!fullTexture) { - sr = QRectF(innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(), - innerSourceRect.y() + (m_subSourceRect.top() - floorTop) * innerSourceRect.height(), - m_subSourceRect.width() * innerSourceRect.width(), - m_subSourceRect.height() * innerSourceRect.height()); - } else { - sr = QRectF(m_subSourceRect.left() - floorLeft, m_subSourceRect.top() - floorTop, - m_subSourceRect.width(), m_subSourceRect.height()); - } - if (m_mirror) { - qreal oldLeft = sr.left(); - sr.setLeft(sr.right()); - sr.setRight(oldLeft); - } - - if (m_antialiasing) { - QSGGeometry *g = geometry(); - Q_ASSERT(g != &m_geometry); - g->allocate(8, 14); - g->setDrawingMode(GL_TRIANGLE_STRIP); - SmoothVertex *vertices = reinterpret_cast<SmoothVertex *>(g->vertexData()); - float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height()) - ? m_targetRect.width() : m_targetRect.height()) * 0.5f; - float sx = float(sr.width() / m_targetRect.width()); - float sy = float(sr.height() / m_targetRect.height()); - for (int d = -1; d <= 1; d += 2) { - for (int j = 0; j < 2; ++j) { - for (int i = 0; i < 2; ++i, ++vertices) { - vertices->x = m_targetRect.x() + i * m_targetRect.width(); - vertices->y = m_targetRect.y() + j * m_targetRect.height(); - vertices->u = sr.x() + i * sr.width(); - vertices->v = sr.y() + j * sr.height(); - vertices->dx = (i == 0 ? delta : -delta) * d; - vertices->dy = (j == 0 ? delta : -delta) * d; - vertices->du = (d < 0 ? 0 : vertices->dx * sx); - vertices->dv = (d < 0 ? 0 : vertices->dy * sy); - } - } - } - Q_ASSERT(vertices - g->vertexCount() == g->vertexData()); - static const quint16 indices[] = { - 0, 4, 1, 5, 3, 7, 2, 6, 0, 4, - 4, 6, 5, 7 - }; - Q_ASSERT(g->sizeOfIndex() * g->indexCount() == sizeof(indices)); - memcpy(g->indexDataAsUShort(), indices, sizeof(indices)); - } else { - m_geometry.allocate(4); - m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); - QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_targetRect, sr); - } - } else { - int hCells = hTiles; - int vCells = vTiles; - if (m_innerTargetRect.width() == 0) - hCells = 0; - if (m_innerTargetRect.left() != m_targetRect.left()) - ++hCells; - if (m_innerTargetRect.right() != m_targetRect.right()) - ++hCells; - if (m_innerTargetRect.height() == 0) - vCells = 0; - if (m_innerTargetRect.top() != m_targetRect.top()) - ++vCells; - if (m_innerTargetRect.bottom() != m_targetRect.bottom()) - ++vCells; - QVarLengthArray<X, 32> xData(2 * hCells); - QVarLengthArray<Y, 32> yData(2 * vCells); - X *xs = xData.data(); - Y *ys = yData.data(); - - if (m_innerTargetRect.left() != m_targetRect.left()) { - xs[0].x = m_targetRect.left(); - xs[0].tx = sourceRect.left(); - xs[1].x = m_innerTargetRect.left(); - xs[1].tx = innerSourceRect.left(); - xs += 2; - } - if (m_innerTargetRect.width() != 0) { - xs[0].x = m_innerTargetRect.left(); - xs[0].tx = innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(); - ++xs; - float b = m_innerTargetRect.width() / m_subSourceRect.width(); - float a = m_innerTargetRect.x() - m_subSourceRect.x() * b; - for (int i = floorLeft + 1; i <= ceilRight - 1; ++i) { - xs[0].x = xs[1].x = a + b * i; - xs[0].tx = innerSourceRect.right(); - xs[1].tx = innerSourceRect.left(); - xs += 2; - } - xs[0].x = m_innerTargetRect.right(); - xs[0].tx = innerSourceRect.x() + (m_subSourceRect.right() - ceilRight + 1) * innerSourceRect.width(); - ++xs; - } - if (m_innerTargetRect.right() != m_targetRect.right()) { - xs[0].x = m_innerTargetRect.right(); - xs[0].tx = innerSourceRect.right(); - xs[1].x = m_targetRect.right(); - xs[1].tx = sourceRect.right(); - xs += 2; - } - Q_ASSERT(xs == xData.data() + xData.size()); - if (m_mirror) { - float leftPlusRight = m_targetRect.left() + m_targetRect.right(); - int count = xData.size(); - xs = xData.data(); - for (int i = 0; i < count >> 1; ++i) - qSwap(xs[i], xs[count - 1 - i]); - for (int i = 0; i < count; ++i) - xs[i].x = leftPlusRight - xs[i].x; - } - - if (m_innerTargetRect.top() != m_targetRect.top()) { - ys[0].y = m_targetRect.top(); - ys[0].ty = sourceRect.top(); - ys[1].y = m_innerTargetRect.top(); - ys[1].ty = innerSourceRect.top(); - ys += 2; - } - if (m_innerTargetRect.height() != 0) { - ys[0].y = m_innerTargetRect.top(); - ys[0].ty = innerSourceRect.y() + (m_subSourceRect.top() - floorTop) * innerSourceRect.height(); - ++ys; - float b = m_innerTargetRect.height() / m_subSourceRect.height(); - float a = m_innerTargetRect.y() - m_subSourceRect.y() * b; - for (int i = floorTop + 1; i <= ceilBottom - 1; ++i) { - ys[0].y = ys[1].y = a + b * i; - ys[0].ty = innerSourceRect.bottom(); - ys[1].ty = innerSourceRect.top(); - ys += 2; - } - ys[0].y = m_innerTargetRect.bottom(); - ys[0].ty = innerSourceRect.y() + (m_subSourceRect.bottom() - ceilBottom + 1) * innerSourceRect.height(); - ++ys; - } - if (m_innerTargetRect.bottom() != m_targetRect.bottom()) { - ys[0].y = m_innerTargetRect.bottom(); - ys[0].ty = innerSourceRect.bottom(); - ys[1].y = m_targetRect.bottom(); - ys[1].ty = sourceRect.bottom(); - ys += 2; - } - Q_ASSERT(ys == yData.data() + yData.size()); - - if (m_antialiasing) { - QSGGeometry *g = geometry(); - Q_ASSERT(g != &m_geometry); - - g->allocate(hCells * vCells * 4 + (hCells + vCells - 1) * 4, - hCells * vCells * 6 + (hCells + vCells) * 12); - g->setDrawingMode(GL_TRIANGLES); - SmoothVertex *vertices = reinterpret_cast<SmoothVertex *>(g->vertexData()); - memset(vertices, 0, g->vertexCount() * g->sizeOfVertex()); - quint16 *indices = g->indexDataAsUShort(); - - // The deltas are how much the fuzziness can reach into the image. - // Only the border vertices are moved by the vertex shader, so the fuzziness - // can't reach further into the image than the closest interior vertices. - float leftDx = xData.at(1).x - xData.at(0).x; - float rightDx = xData.at(xData.size() - 1).x - xData.at(xData.size() - 2).x; - float topDy = yData.at(1).y - yData.at(0).y; - float bottomDy = yData.at(yData.size() - 1).y - yData.at(yData.size() - 2).y; - - float leftDu = xData.at(1).tx - xData.at(0).tx; - float rightDu = xData.at(xData.size() - 1).tx - xData.at(xData.size() - 2).tx; - float topDv = yData.at(1).ty - yData.at(0).ty; - float bottomDv = yData.at(yData.size() - 1).ty - yData.at(yData.size() - 2).ty; - - if (hCells == 1) { - leftDx = rightDx *= 0.5f; - leftDu = rightDu *= 0.5f; - } - if (vCells == 1) { - topDy = bottomDy *= 0.5f; - topDv = bottomDv *= 0.5f; - } - - // This delta is how much the fuzziness can reach out from the image. - float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height()) - ? m_targetRect.width() : m_targetRect.height()) * 0.5f; - - quint16 index = 0; - ys = yData.data(); - for (int j = 0; j < vCells; ++j, ys += 2) { - xs = xData.data(); - bool isTop = j == 0; - bool isBottom = j == vCells - 1; - for (int i = 0; i < hCells; ++i, xs += 2) { - bool isLeft = i == 0; - bool isRight = i == hCells - 1; - - SmoothVertex *v = vertices + index; - - quint16 topLeft = index; - for (int k = (isTop || isLeft ? 2 : 1); k--; ++v, ++index) { - v->x = xs[0].x; - v->u = xs[0].tx; - v->y = ys[0].y; - v->v = ys[0].ty; - } - - quint16 topRight = index; - for (int k = (isTop || isRight ? 2 : 1); k--; ++v, ++index) { - v->x = xs[1].x; - v->u = xs[1].tx; - v->y = ys[0].y; - v->v = ys[0].ty; - } - - quint16 bottomLeft = index; - for (int k = (isBottom || isLeft ? 2 : 1); k--; ++v, ++index) { - v->x = xs[0].x; - v->u = xs[0].tx; - v->y = ys[1].y; - v->v = ys[1].ty; - } - - quint16 bottomRight = index; - for (int k = (isBottom || isRight ? 2 : 1); k--; ++v, ++index) { - v->x = xs[1].x; - v->u = xs[1].tx; - v->y = ys[1].y; - v->v = ys[1].ty; - } - - appendQuad(&indices, topLeft, topRight, bottomLeft, bottomRight); - - if (isTop) { - vertices[topLeft].dy = vertices[topRight].dy = topDy; - vertices[topLeft].dv = vertices[topRight].dv = topDv; - vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -delta; - appendQuad(&indices, topLeft + 1, topRight + 1, topLeft, topRight); - } - - if (isBottom) { - vertices[bottomLeft].dy = vertices[bottomRight].dy = -bottomDy; - vertices[bottomLeft].dv = vertices[bottomRight].dv = -bottomDv; - vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = delta; - appendQuad(&indices, bottomLeft, bottomRight, bottomLeft + 1, bottomRight + 1); - } - - if (isLeft) { - vertices[topLeft].dx = vertices[bottomLeft].dx = leftDx; - vertices[topLeft].du = vertices[bottomLeft].du = leftDu; - vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -delta; - appendQuad(&indices, topLeft + 1, topLeft, bottomLeft + 1, bottomLeft); - } - - if (isRight) { - vertices[topRight].dx = vertices[bottomRight].dx = -rightDx; - vertices[topRight].du = vertices[bottomRight].du = -rightDu; - vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = delta; - appendQuad(&indices, topRight, topRight + 1, bottomRight, bottomRight + 1); - } - } - } - - Q_ASSERT(index == g->vertexCount()); - Q_ASSERT(indices - g->indexCount() == g->indexData()); - } else { - m_geometry.allocate(hCells * vCells * 4, hCells * vCells * 6); - m_geometry.setDrawingMode(GL_TRIANGLES); - QSGGeometry::TexturedPoint2D *vertices = m_geometry.vertexDataAsTexturedPoint2D(); - ys = yData.data(); - for (int j = 0; j < vCells; ++j, ys += 2) { - xs = xData.data(); - for (int i = 0; i < hCells; ++i, xs += 2) { - vertices[0].x = vertices[2].x = xs[0].x; - vertices[0].tx = vertices[2].tx = xs[0].tx; - vertices[1].x = vertices[3].x = xs[1].x; - vertices[1].tx = vertices[3].tx = xs[1].tx; - - vertices[0].y = vertices[1].y = ys[0].y; - vertices[0].ty = vertices[1].ty = ys[0].ty; - vertices[2].y = vertices[3].y = ys[1].y; - vertices[2].ty = vertices[3].ty = ys[1].ty; - - vertices += 4; - } - } - - quint16 *indices = m_geometry.indexDataAsUShort(); - for (int i = 0; i < 4 * vCells * hCells; i += 4) - appendQuad(&indices, i, i + 1, i + 2, i + 3); - } - } + { + bool npotSupported = ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat); + const bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); + wrapSupported = npotSupported || !isNpot; } - markDirty(DirtyGeometry); - m_dirtyGeometry = false; + + return wrapSupported; } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultimagenode_p.h b/src/quick/scenegraph/qsgdefaultimagenode_p.h index 2d8abc1d35..688c5a5039 100644 --- a/src/quick/scenegraph/qsgdefaultimagenode_p.h +++ b/src/quick/scenegraph/qsgdefaultimagenode_p.h @@ -53,6 +53,7 @@ // #include <private/qsgadaptationlayer_p.h> +#include <private/qsgbasicimagenode_p.h> #include <QtQuick/qsgtexturematerial.h> QT_BEGIN_NAMESPACE @@ -65,47 +66,30 @@ public: void setTexture(QSGTexture *texture); protected: - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; + QSGMaterialType *type() const override; + QSGMaterialShader *createShader() const override; }; -class Q_QUICK_PRIVATE_EXPORT QSGDefaultImageNode : public QSGImageNode +class Q_QUICK_PRIVATE_EXPORT QSGDefaultImageNode : public QSGBasicImageNode { public: QSGDefaultImageNode(); - virtual void setTargetRect(const QRectF &rect); - virtual void setInnerTargetRect(const QRectF &rect); - virtual void setInnerSourceRect(const QRectF &rect); - virtual void setSubSourceRect(const QRectF &rect); - virtual void setTexture(QSGTexture *t); - virtual void setAntialiasing(bool antialiasing); - virtual void setMirror(bool mirror); - virtual void update(); - virtual void setMipmapFiltering(QSGTexture::Filtering filtering); - virtual void setFiltering(QSGTexture::Filtering filtering); - virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode); - virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode); + void setMipmapFiltering(QSGTexture::Filtering filtering) override; + void setFiltering(QSGTexture::Filtering filtering) override; + void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) override; + void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) override; - virtual void preprocess(); + void updateMaterialAntialiasing() override; + void setMaterialTexture(QSGTexture *texture) override; + QSGTexture *materialTexture() const override; + bool updateMaterialBlending() override; + bool supportsWrap(const QSize &size) const override; private: - void updateGeometry(); - - QRectF m_targetRect; - QRectF m_innerTargetRect; - QRectF m_innerSourceRect; - QRectF m_subSourceRect; - QSGOpaqueTextureMaterial m_material; QSGTextureMaterial m_materialO; QSGSmoothTextureMaterial m_smoothMaterial; - - uint m_antialiasing : 1; - uint m_mirror : 1; - uint m_dirtyGeometry : 1; - - QSGGeometry m_geometry; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp index 2f1c1d454c..ad5b57ff83 100644 --- a/src/quick/scenegraph/qsgdefaultlayer.cpp +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -40,8 +40,12 @@ #include <private/qqmlglobal_p.h> #include <private/qsgrenderer_p.h> +#include <private/qsgdefaultrendercontext_p.h> -#include <QOpenGLFramebufferObject> +#include <QtGui/QOpenGLFramebufferObject> +#include <QtGui/QOpenGLFunctions> + +#include <QtQuick/private/qsgdepthstencilbuffer_p.h> #ifdef QSG_DEBUG_FBO_OVERLAY DEFINE_BOOL_CONFIG_OPTION(qmlFboOverlay, QML_FBO_OVERLAY) @@ -95,7 +99,6 @@ QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) #ifdef QSG_DEBUG_FBO_OVERLAY , m_debugOverlay(0) #endif - , m_context(context) , m_mipmap(false) , m_live(true) , m_recursive(false) @@ -106,6 +109,7 @@ QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) , m_mirrorHorizontal(false) , m_mirrorVertical(true) { + m_context = static_cast<QSGDefaultRenderContext *>(context); } QSGDefaultLayer::~QSGDefaultLayer() diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h index 8bb565f845..ae39994096 100644 --- a/src/quick/scenegraph/qsgdefaultlayer_p.h +++ b/src/quick/scenegraph/qsgdefaultlayer_p.h @@ -54,8 +54,14 @@ #include <private/qsgcontext_p.h> #include <qsgsimplerectnode.h> +QT_BEGIN_NAMESPACE + #define QSG_DEBUG_FBO_OVERLAY +class QOpenGLFramebufferObject; +class QSGDepthStencilBuffer; +class QSGDefaultRenderContext; + class Q_QUICK_PRIVATE_EXPORT QSGDefaultLayer : public QSGLayer { Q_OBJECT @@ -131,7 +137,7 @@ private: QSGSimpleRectNode *m_debugOverlay; #endif - QSGRenderContext *m_context; + QSGDefaultRenderContext *m_context; uint m_mipmap : 1; uint m_live : 1; @@ -144,4 +150,6 @@ private: uint m_mirrorVertical : 1; }; +QT_END_NAMESPACE + #endif // QSGDEFAULTLAYER_P_H diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp index 5ef52e8722..117a9272e5 100644 --- a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp +++ b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp @@ -38,8 +38,6 @@ ** ****************************************************************************/ - - #include "qsgdefaultrectanglenode_p.h" #include <QtQuick/qsgvertexcolormaterial.h> @@ -52,59 +50,6 @@ QT_BEGIN_NAMESPACE -namespace -{ - struct Color4ub - { - unsigned char r, g, b, a; - }; - - Color4ub operator *(Color4ub c, float t) { c.a *= t; c.r *= t; c.g *= t; c.b *= t; return c; } - Color4ub operator +(Color4ub a, Color4ub b) { a.a += b.a; a.r += b.r; a.g += b.g; a.b += b.b; return a; } - - inline Color4ub colorToColor4ub(const QColor &c) - { - Color4ub color = { uchar(qRound(c.redF() * c.alphaF() * 255)), - uchar(qRound(c.greenF() * c.alphaF() * 255)), - uchar(qRound(c.blueF() * c.alphaF() * 255)), - uchar(qRound(c.alphaF() * 255)) - }; - return color; - } - - // Same layout as QSGGeometry::ColoredPoint2D, but uses Color4ub for convenience. - struct Vertex - { - float x, y; - Color4ub color; - void set(float nx, float ny, Color4ub ncolor) - { - x = nx; y = ny; color = ncolor; - } - }; - - struct SmoothVertex : public Vertex - { - float dx, dy; - void set(float nx, float ny, Color4ub ncolor, float ndx, float ndy) - { - Vertex::set(nx, ny, ncolor); - dx = ndx; dy = ndy; - } - }; - - const QSGGeometry::AttributeSet &smoothAttributeSet() - { - static QSGGeometry::Attribute data[] = { - QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), - QSGGeometry::Attribute::create(1, 4, GL_UNSIGNED_BYTE, false), - QSGGeometry::Attribute::create(2, 2, GL_FLOAT, false) - }; - static QSGGeometry::AttributeSet attrs = { 3, sizeof(SmoothVertex), data }; - return attrs; - } -} - class SmoothColorMaterialShader : public QSGMaterialShader { public: @@ -183,604 +128,32 @@ QSGMaterialShader *QSGSmoothColorMaterial::createShader() const return new SmoothColorMaterialShader; } - QSGDefaultRectangleNode::QSGDefaultRectangleNode() - : m_radius(0) - , m_pen_width(0) - , m_aligned(true) - , m_antialiasing(false) - , m_gradient_is_opaque(true) - , m_dirty_geometry(false) - , m_geometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 0) { - setGeometry(&m_geometry); setMaterial(&m_material); - -#ifdef QSG_RUNTIME_DESCRIPTION - qsgnode_set_description(this, QLatin1String("rectangle")); -#endif -} - -void QSGDefaultRectangleNode::setRect(const QRectF &rect) -{ - if (rect == m_rect) - return; - m_rect = rect; - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::setColor(const QColor &color) -{ - if (color == m_color) - return; - m_color = color; - if (m_gradient_stops.isEmpty()) - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::setPenColor(const QColor &color) -{ - if (color == m_border_color) - return; - m_border_color = color; - if (m_pen_width > 0) - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::setPenWidth(qreal width) -{ - if (width == m_pen_width) - return; - m_pen_width = width; - m_dirty_geometry = true; -} - - -void QSGDefaultRectangleNode::setGradientStops(const QGradientStops &stops) -{ - if (stops.constData() == m_gradient_stops.constData()) - return; - - m_gradient_stops = stops; - - m_gradient_is_opaque = true; - for (int i = 0; i < stops.size(); ++i) - m_gradient_is_opaque &= stops.at(i).second.alpha() == 0xff; - m_dirty_geometry = true; } -void QSGDefaultRectangleNode::setRadius(qreal radius) +void QSGDefaultRectangleNode::updateMaterialAntialiasing() { - if (radius == m_radius) - return; - m_radius = radius; - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::setAntialiasing(bool antialiasing) -{ - if (antialiasing == m_antialiasing) - return; - m_antialiasing = antialiasing; - if (m_antialiasing) { + if (m_antialiasing) setMaterial(&m_smoothMaterial); - setGeometry(new QSGGeometry(smoothAttributeSet(), 0)); - setFlag(OwnsGeometry, true); - } else { + else setMaterial(&m_material); - setGeometry(&m_geometry); - setFlag(OwnsGeometry, false); - } - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::setAligned(bool aligned) -{ - if (aligned == m_aligned) - return; - m_aligned = aligned; - m_dirty_geometry = true; -} - -void QSGDefaultRectangleNode::update() -{ - if (m_dirty_geometry) { - updateGeometry(); - m_dirty_geometry = false; - - QSGNode::DirtyState state = QSGNode::DirtyGeometry; - // smoothed material is always blended, so no change in material state - if (material() == &m_material) { - bool wasBlending = (m_material.flags() & QSGMaterial::Blending); - bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque) - || (m_color.alpha() < 255 && m_color.alpha() != 0) - || (m_pen_width > 0 && m_border_color.alpha() < 255); - if (wasBlending != isBlending) { - m_material.setFlag(QSGMaterial::Blending, isBlending); - state |= QSGNode::DirtyMaterial; - } - } - - markDirty(state); - } } -void QSGDefaultRectangleNode::updateGeometry() +void QSGDefaultRectangleNode::updateMaterialBlending(QSGNode::DirtyState *state) { - float width = float(m_rect.width()); - float height = float(m_rect.height()); - float penWidth = qMin(qMin(width, height) * 0.5f, float(m_pen_width)); - - if (m_aligned) - penWidth = qRound(penWidth); - - QSGGeometry *g = geometry(); - g->setDrawingMode(GL_TRIANGLE_STRIP); - int vertexStride = g->sizeOfVertex(); - - union { - Vertex *vertices; - SmoothVertex *smoothVertices; - }; - - Color4ub fillColor = colorToColor4ub(m_color); - Color4ub borderColor = colorToColor4ub(m_border_color); - Color4ub transparent = { 0, 0, 0, 0 }; - const QGradientStops &stops = m_gradient_stops; - - int nextGradientStop = 0; - float gradientPos = penWidth / height; - while (nextGradientStop < stops.size() && stops.at(nextGradientStop).first <= gradientPos) - ++nextGradientStop; - int lastGradientStop = stops.size() - 1; - float lastGradientPos = 1.0f - penWidth / height; - while (lastGradientStop >= nextGradientStop && stops.at(lastGradientStop).first >= lastGradientPos) - --lastGradientStop; - int gradientIntersections = (lastGradientStop - nextGradientStop + 1); - - if (m_radius > 0) { - // Rounded corners. - - // Radius should never exceeds half of the width or half of the height - float radius = qMin(qMin(width, height) * 0.5f, float(m_radius)); - QRectF innerRect = m_rect; - innerRect.adjust(radius, radius, -radius, -radius); - - float innerRadius = radius - penWidth * 1.0f; - float outerRadius = radius; - float delta = qMin(width, height) * 0.5f; - - // Number of segments per corner, approximately one per 3 pixels. - int segments = qBound(3, qCeil(outerRadius * (M_PI / 6)), 18); - - /* - - --+--__ - --+--__--__ - | --__--__ - | seg --__--+ - --+-__ ment _+ \ - --+-__--__ - \ \ - --__--+ se \ \ - + \ g \ \ - \ \ m \ \ - -----------+--+ e \ \ <- gradient line - \ \ nt\ \ - fill +--+----+--+ - | | | | - border - inner AA outer AA (AA = antialiasing) - - */ - - int innerVertexCount = (segments + 1) * 4 + gradientIntersections * 2; - int outerVertexCount = (segments + 1) * 4; - int vertexCount = innerVertexCount; - if (m_antialiasing || penWidth) - vertexCount += innerVertexCount; - if (penWidth) - vertexCount += outerVertexCount; - if (m_antialiasing && penWidth) - vertexCount += outerVertexCount; - - int fillIndexCount = innerVertexCount; - int innerAAIndexCount = innerVertexCount * 2 + 2; - int borderIndexCount = innerVertexCount * 2 + 2; - int outerAAIndexCount = outerVertexCount * 2 + 2; - int indexCount = 0; - int fillHead = 0; - int innerAAHead = 0; - int innerAATail = 0; - int borderHead = 0; - int borderTail = 0; - int outerAAHead = 0; - int outerAATail = 0; - bool hasFill = m_color.alpha() > 0 || !stops.isEmpty(); - if (hasFill) - indexCount += fillIndexCount; - if (m_antialiasing) { - innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1; - indexCount += innerAAIndexCount; - } - if (penWidth) { - borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1; - indexCount += borderIndexCount; - } - if (m_antialiasing && penWidth) { - outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1; - indexCount += outerAAIndexCount; - } - - g->allocate(vertexCount, indexCount); - vertices = reinterpret_cast<Vertex *>(g->vertexData()); - memset(vertices, 0, vertexCount * vertexStride); - quint16 *indices = g->indexDataAsUShort(); - quint16 index = 0; - - float py = 0; // previous inner y-coordinate. - float plx = 0; // previous inner left x-coordinate. - float prx = 0; // previous inner right x-coordinate. - - float angle = 0.5f * float(M_PI) / segments; - float cosStep = qFastCos(angle); - float sinStep = qFastSin(angle); - - for (int part = 0; part < 2; ++part) { - float c = 1 - part; - float s = part; - for (int i = 0; i <= segments; ++i) { - float y, lx, rx; - if (innerRadius > 0) { - y = (part ? innerRect.bottom() : innerRect.top()) - innerRadius * c; // current inner y-coordinate. - lx = innerRect.left() - innerRadius * s; // current inner left x-coordinate. - rx = innerRect.right() + innerRadius * s; // current inner right x-coordinate. - gradientPos = ((part ? innerRect.height() : 0) + radius - innerRadius * c) / height; - } else { - y = (part ? innerRect.bottom() + innerRadius : innerRect.top() - innerRadius); // current inner y-coordinate. - lx = innerRect.left() - innerRadius; // current inner left x-coordinate. - rx = innerRect.right() + innerRadius; // current inner right x-coordinate. - gradientPos = ((part ? innerRect.height() + innerRadius : -innerRadius) + radius) / height; - } - float Y = (part ? innerRect.bottom() : innerRect.top()) - outerRadius * c; // current outer y-coordinate. - float lX = innerRect.left() - outerRadius * s; // current outer left x-coordinate. - float rX = innerRect.right() + outerRadius * s; // current outer right x-coordinate. - - while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) { - // Insert vertices at gradient stops. - float gy = (innerRect.top() - radius) + stops.at(nextGradientStop).first * height; - float t = (gy - py) / (y - py); - float glx = plx * (1 - t) + t * lx; - float grx = prx * (1 - t) + t * rx; - - fillColor = colorToColor4ub(stops.at(nextGradientStop).second); - - if (hasFill) { - indices[fillHead++] = index; - indices[fillHead++] = index + 1; - } - - if (penWidth) { - --borderHead; - indices[borderHead] = indices[borderHead + 2]; - indices[--borderHead] = index + 2; - indices[borderTail++] = index + 3; - indices[borderTail] = indices[borderTail - 2]; - ++borderTail; - } - - if (m_antialiasing) { - indices[--innerAAHead] = index + 2; - indices[--innerAAHead] = index; - indices[innerAATail++] = index + 1; - indices[innerAATail++] = index + 3; - - bool lower = stops.at(nextGradientStop).first > 0.5f; - float dy = lower ? qMin(0.0f, height - gy - delta) : qMax(0.0f, delta - gy); - smoothVertices[index++].set(grx, gy, fillColor, width - grx - delta, dy); - smoothVertices[index++].set(glx, gy, fillColor, delta - glx, dy); - if (penWidth) { - smoothVertices[index++].set(grx, gy, borderColor, 0.49f * penWidth * s, -0.49f * penWidth * c); - smoothVertices[index++].set(glx, gy, borderColor, -0.49f * penWidth * s, -0.49f * penWidth * c); - } else { - dy = lower ? delta : -delta; - smoothVertices[index++].set(grx, gy, transparent, delta, dy); - smoothVertices[index++].set(glx, gy, transparent, -delta, dy); - } - } else { - vertices[index++].set(grx, gy, fillColor); - vertices[index++].set(glx, gy, fillColor); - if (penWidth) { - vertices[index++].set(grx, gy, borderColor); - vertices[index++].set(glx, gy, borderColor); - } - } - ++nextGradientStop; - } - - if (!stops.isEmpty()) { - if (nextGradientStop == 0) { - fillColor = colorToColor4ub(stops.at(0).second); - } else if (nextGradientStop == stops.size()) { - fillColor = colorToColor4ub(stops.last().second); - } else { - const QGradientStop &prev = stops.at(nextGradientStop - 1); - const QGradientStop &next = stops.at(nextGradientStop); - float t = (gradientPos - prev.first) / (next.first - prev.first); - fillColor = colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t; - } - } - - if (hasFill) { - indices[fillHead++] = index; - indices[fillHead++] = index + 1; - } - - if (penWidth) { - indices[--borderHead] = index + 4; - indices[--borderHead] = index + 2; - indices[borderTail++] = index + 3; - indices[borderTail++] = index + 5; - } - - if (m_antialiasing) { - indices[--innerAAHead] = index + 2; - indices[--innerAAHead] = index; - indices[innerAATail++] = index + 1; - indices[innerAATail++] = index + 3; - - float dy = part ? qMin(0.0f, height - y - delta) : qMax(0.0f, delta - y); - smoothVertices[index++].set(rx, y, fillColor, width - rx - delta, dy); - smoothVertices[index++].set(lx, y, fillColor, delta - lx, dy); - - dy = part ? delta : -delta; - if (penWidth) { - smoothVertices[index++].set(rx, y, borderColor, 0.49f * penWidth * s, -0.49f * penWidth * c); - smoothVertices[index++].set(lx, y, borderColor, -0.49f * penWidth * s, -0.49f * penWidth * c); - smoothVertices[index++].set(rX, Y, borderColor, -0.49f * penWidth * s, 0.49f * penWidth * c); - smoothVertices[index++].set(lX, Y, borderColor, 0.49f * penWidth * s, 0.49f * penWidth * c); - smoothVertices[index++].set(rX, Y, transparent, delta, dy); - smoothVertices[index++].set(lX, Y, transparent, -delta, dy); - - indices[--outerAAHead] = index - 2; - indices[--outerAAHead] = index - 4; - indices[outerAATail++] = index - 3; - indices[outerAATail++] = index - 1; - } else { - smoothVertices[index++].set(rx, y, transparent, delta, dy); - smoothVertices[index++].set(lx, y, transparent, -delta, dy); - } - } else { - vertices[index++].set(rx, y, fillColor); - vertices[index++].set(lx, y, fillColor); - if (penWidth) { - vertices[index++].set(rx, y, borderColor); - vertices[index++].set(lx, y, borderColor); - vertices[index++].set(rX, Y, borderColor); - vertices[index++].set(lX, Y, borderColor); - } - } - - py = y; - plx = lx; - prx = rx; - - // Rotate - qreal tmp = c; - c = c * cosStep - s * sinStep; - s = s * cosStep + tmp * sinStep; - } - } - Q_ASSERT(index == vertexCount); - - // Close the triangle strips. - if (m_antialiasing) { - indices[--innerAAHead] = indices[innerAATail - 1]; - indices[--innerAAHead] = indices[innerAATail - 2]; - Q_ASSERT(innerAATail <= indexCount); - } - if (penWidth) { - indices[--borderHead] = indices[borderTail - 1]; - indices[--borderHead] = indices[borderTail - 2]; - Q_ASSERT(borderTail <= indexCount); - } - if (m_antialiasing && penWidth) { - indices[--outerAAHead] = indices[outerAATail - 1]; - indices[--outerAAHead] = indices[outerAATail - 2]; - Q_ASSERT(outerAATail == indexCount); - } - } else { - // Straight corners. - QRectF innerRect = m_rect; - QRectF outerRect = m_rect; - - if (penWidth) - innerRect.adjust(1.0f * penWidth, 1.0f * penWidth, -1.0f * penWidth, -1.0f * penWidth); - - float delta = qMin(width, height) * 0.5f; - int innerVertexCount = 4 + gradientIntersections * 2; - int outerVertexCount = 4; - int vertexCount = innerVertexCount; - if (m_antialiasing || penWidth) - vertexCount += innerVertexCount; - if (penWidth) - vertexCount += outerVertexCount; - if (m_antialiasing && penWidth) - vertexCount += outerVertexCount; - - int fillIndexCount = innerVertexCount; - int innerAAIndexCount = innerVertexCount * 2 + 2; - int borderIndexCount = innerVertexCount * 2 + 2; - int outerAAIndexCount = outerVertexCount * 2 + 2; - int indexCount = 0; - int fillHead = 0; - int innerAAHead = 0; - int innerAATail = 0; - int borderHead = 0; - int borderTail = 0; - int outerAAHead = 0; - int outerAATail = 0; - bool hasFill = m_color.alpha() > 0 || !stops.isEmpty(); - if (hasFill) - indexCount += fillIndexCount; - if (m_antialiasing) { - innerAATail = innerAAHead = indexCount + (innerAAIndexCount >> 1) + 1; - indexCount += innerAAIndexCount; - } - if (penWidth) { - borderTail = borderHead = indexCount + (borderIndexCount >> 1) + 1; - indexCount += borderIndexCount; - } - if (m_antialiasing && penWidth) { - outerAATail = outerAAHead = indexCount + (outerAAIndexCount >> 1) + 1; - indexCount += outerAAIndexCount; - } - - g->allocate(vertexCount, indexCount); - vertices = reinterpret_cast<Vertex *>(g->vertexData()); - memset(vertices, 0, vertexCount * vertexStride); - quint16 *indices = g->indexDataAsUShort(); - quint16 index = 0; - - float lx = innerRect.left(); - float rx = innerRect.right(); - float lX = outerRect.left(); - float rX = outerRect.right(); - - for (int part = -1; part <= 1; part += 2) { - float y = (part == 1 ? innerRect.bottom() : innerRect.top()); - float Y = (part == 1 ? outerRect.bottom() : outerRect.top()); - gradientPos = (y - innerRect.top() + penWidth) / height; - - while (nextGradientStop <= lastGradientStop && stops.at(nextGradientStop).first <= gradientPos) { - // Insert vertices at gradient stops. - float gy = (innerRect.top() - penWidth) + stops.at(nextGradientStop).first * height; - - fillColor = colorToColor4ub(stops.at(nextGradientStop).second); - - if (hasFill) { - indices[fillHead++] = index; - indices[fillHead++] = index + 1; - } - - if (penWidth) { - --borderHead; - indices[borderHead] = indices[borderHead + 2]; - indices[--borderHead] = index + 2; - indices[borderTail++] = index + 3; - indices[borderTail] = indices[borderTail - 2]; - ++borderTail; - } - - if (m_antialiasing) { - indices[--innerAAHead] = index + 2; - indices[--innerAAHead] = index; - indices[innerAATail++] = index + 1; - indices[innerAATail++] = index + 3; - - bool lower = stops.at(nextGradientStop).first > 0.5f; - float dy = lower ? qMin(0.0f, height - gy - delta) : qMax(0.0f, delta - gy); - smoothVertices[index++].set(rx, gy, fillColor, width - rx - delta, dy); - smoothVertices[index++].set(lx, gy, fillColor, delta - lx, dy); - if (penWidth) { - smoothVertices[index++].set(rx, gy, borderColor, 0.49f * penWidth, (lower ? 0.49f : -0.49f) * penWidth); - smoothVertices[index++].set(lx, gy, borderColor, -0.49f * penWidth, (lower ? 0.49f : -0.49f) * penWidth); - } else { - smoothVertices[index++].set(rx, gy, transparent, delta, lower ? delta : -delta); - smoothVertices[index++].set(lx, gy, transparent, -delta, lower ? delta : -delta); - } - } else { - vertices[index++].set(rx, gy, fillColor); - vertices[index++].set(lx, gy, fillColor); - if (penWidth) { - vertices[index++].set(rx, gy, borderColor); - vertices[index++].set(lx, gy, borderColor); - } - } - ++nextGradientStop; - } - - if (!stops.isEmpty()) { - if (nextGradientStop == 0) { - fillColor = colorToColor4ub(stops.at(0).second); - } else if (nextGradientStop == stops.size()) { - fillColor = colorToColor4ub(stops.last().second); - } else { - const QGradientStop &prev = stops.at(nextGradientStop - 1); - const QGradientStop &next = stops.at(nextGradientStop); - float t = (gradientPos - prev.first) / (next.first - prev.first); - fillColor = colorToColor4ub(prev.second) * (1 - t) + colorToColor4ub(next.second) * t; - } - } - - if (hasFill) { - indices[fillHead++] = index; - indices[fillHead++] = index + 1; - } - - if (penWidth) { - indices[--borderHead] = index + 4; - indices[--borderHead] = index + 2; - indices[borderTail++] = index + 3; - indices[borderTail++] = index + 5; - } - - if (m_antialiasing) { - indices[--innerAAHead] = index + 2; - indices[--innerAAHead] = index; - indices[innerAATail++] = index + 1; - indices[innerAATail++] = index + 3; - - float dy = part == 1 ? qMin(0.0f, height - y - delta) : qMax(0.0f, delta - y); - smoothVertices[index++].set(rx, y, fillColor, width - rx - delta, dy); - smoothVertices[index++].set(lx, y, fillColor, delta - lx, dy); - - if (penWidth) { - smoothVertices[index++].set(rx, y, borderColor, 0.49f * penWidth, 0.49f * penWidth * part); - smoothVertices[index++].set(lx, y, borderColor, -0.49f * penWidth, 0.49f * penWidth * part); - smoothVertices[index++].set(rX, Y, borderColor, -0.49f * penWidth, -0.49f * penWidth * part); - smoothVertices[index++].set(lX, Y, borderColor, 0.49f * penWidth, -0.49f * penWidth * part); - smoothVertices[index++].set(rX, Y, transparent, delta, delta * part); - smoothVertices[index++].set(lX, Y, transparent, -delta, delta * part); - - indices[--outerAAHead] = index - 2; - indices[--outerAAHead] = index - 4; - indices[outerAATail++] = index - 3; - indices[outerAATail++] = index - 1; - } else { - smoothVertices[index++].set(rx, y, transparent, delta, delta * part); - smoothVertices[index++].set(lx, y, transparent, -delta, delta * part); - } - } else { - vertices[index++].set(rx, y, fillColor); - vertices[index++].set(lx, y, fillColor); - if (penWidth) { - vertices[index++].set(rx, y, borderColor); - vertices[index++].set(lx, y, borderColor); - vertices[index++].set(rX, Y, borderColor); - vertices[index++].set(lX, Y, borderColor); - } - } - } - Q_ASSERT(index == vertexCount); - - // Close the triangle strips. - if (m_antialiasing) { - indices[--innerAAHead] = indices[innerAATail - 1]; - indices[--innerAAHead] = indices[innerAATail - 2]; - Q_ASSERT(innerAATail <= indexCount); - } - if (penWidth) { - indices[--borderHead] = indices[borderTail - 1]; - indices[--borderHead] = indices[borderTail - 2]; - Q_ASSERT(borderTail <= indexCount); - } - if (m_antialiasing && penWidth) { - indices[--outerAAHead] = indices[outerAATail - 1]; - indices[--outerAAHead] = indices[outerAATail - 2]; - Q_ASSERT(outerAATail == indexCount); + // smoothed material is always blended, so no change in material state + if (material() == &m_material) { + bool wasBlending = (m_material.flags() & QSGMaterial::Blending); + bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque) + || (m_color.alpha() < 255 && m_color.alpha() != 0) + || (m_pen_width > 0 && m_border_color.alpha() < 255); + if (wasBlending != isBlending) { + m_material.setFlag(QSGMaterial::Blending, isBlending); + *state |= QSGNode::DirtyMaterial; } } } - QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode_p.h b/src/quick/scenegraph/qsgdefaultrectanglenode_p.h index 4cfe921127..f30a3beed7 100644 --- a/src/quick/scenegraph/qsgdefaultrectanglenode_p.h +++ b/src/quick/scenegraph/qsgdefaultrectanglenode_p.h @@ -53,7 +53,7 @@ // #include <private/qsgadaptationlayer_p.h> - +#include <private/qsgbasicrectanglenode_p.h> #include <QtQuick/qsgvertexcolormaterial.h> QT_BEGIN_NAMESPACE @@ -68,45 +68,21 @@ public: int compare(const QSGMaterial *other) const; protected: - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; + QSGMaterialType *type() const override; + QSGMaterialShader *createShader() const override; }; -class Q_QUICK_PRIVATE_EXPORT QSGDefaultRectangleNode : public QSGRectangleNode +class Q_QUICK_PRIVATE_EXPORT QSGDefaultRectangleNode : public QSGBasicRectangleNode { public: QSGDefaultRectangleNode(); - virtual void setRect(const QRectF &rect); - virtual void setColor(const QColor &color); - virtual void setPenColor(const QColor &color); - virtual void setPenWidth(qreal width); - virtual void setGradientStops(const QGradientStops &stops); - virtual void setRadius(qreal radius); - virtual void setAntialiasing(bool antialiasing); - virtual void setAligned(bool aligned); - virtual void update(); - private: - void updateGeometry(); - void updateGradientTexture(); + void updateMaterialAntialiasing() override; + void updateMaterialBlending(QSGNode::DirtyState *state) override; QSGVertexColorMaterial m_material; QSGSmoothColorMaterial m_smoothMaterial; - - QRectF m_rect; - QGradientStops m_gradient_stops; - QColor m_color; - QColor m_border_color; - qreal m_radius; - qreal m_pen_width; - - uint m_aligned : 1; - uint m_antialiasing : 1; - uint m_gradient_is_opaque : 1; - uint m_dirty_geometry : 1; - - QSGGeometry m_geometry; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp new file mode 100644 index 0000000000..92e7f983a0 --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -0,0 +1,302 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgdefaultrendercontext_p.h" + +#include <QtGui/QOpenGLFramebufferObject> + +#include <QtQuick/private/qsgbatchrenderer_p.h> +#include <QtQuick/private/qsgrenderer_p.h> +#include <QtQuick/private/qsgatlastexture_p.h> +#include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h> +#include <QtQuick/private/qsgdistancefieldutil_p.h> + +QT_BEGIN_NAMESPACE + +#define QSG_RENDERCONTEXT_PROPERTY "_q_sgrendercontext" + +QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context) + : QSGRenderContext(context) + , m_gl(nullptr) + , m_depthStencilManager(nullptr) + , m_maxTextureSize(0) + , m_brokenIBOs(false) + , m_serializedRender(false) + , m_attachToGLContext(true) + , m_atlasManager(nullptr) +{ + +} + +/*! + Initializes the scene graph render context with the GL context \a context. This also + emits the ready() signal so that the QML graph can start building scene graph nodes. + */ +void QSGDefaultRenderContext::initialize(void *context) +{ + QOpenGLContext *openglContext = static_cast<QOpenGLContext *>(context); + + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); + + // Sanity check the surface format, in case it was overridden by the application + QSurfaceFormat requested = m_sg->defaultSurfaceFormat(); + QSurfaceFormat actual = openglContext->format(); + if (requested.depthBufferSize() > 0 && actual.depthBufferSize() <= 0) + qWarning("QSGContext::initialize: depth buffer support missing, expect rendering errors"); + if (requested.stencilBufferSize() > 0 && actual.stencilBufferSize() <= 0) + qWarning("QSGContext::initialize: stencil buffer support missing, expect rendering errors"); + + if (!m_atlasManager) + m_atlasManager = new QSGAtlasTexture::Manager(); + + Q_ASSERT_X(!m_gl, "QSGRenderContext::initialize", "already initialized!"); + m_gl = openglContext; + if (m_attachToGLContext) { + Q_ASSERT(!openglContext->property(QSG_RENDERCONTEXT_PROPERTY).isValid()); + openglContext->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant::fromValue(this)); + } + m_sg->renderContextInitialized(this); + +#ifdef Q_OS_LINUX + const char *vendor = (const char *) funcs->glGetString(GL_VENDOR); + if (strstr(vendor, "nouveau")) + m_brokenIBOs = true; + const char *renderer = (const char *) funcs->glGetString(GL_RENDERER); + if (strstr(renderer, "llvmpipe")) + m_serializedRender = true; + if (strstr(vendor, "Hisilicon Technologies") && strstr(renderer, "Immersion.16")) + m_brokenIBOs = true; +#endif + + emit initialized(); +} + + +void QSGDefaultRenderContext::invalidate() +{ + if (!m_gl) + return; + + qDeleteAll(m_texturesToDelete); + m_texturesToDelete.clear(); + + qDeleteAll(m_textures); + m_textures.clear(); + + /* The cleanup of the atlas textures is a bit intriguing. + As part of the cleanup in the threaded render loop, we + do: + 1. call this function + 2. call QCoreApp::sendPostedEvents() to immediately process + any pending deferred deletes. + 3. delete the GL context. + + As textures need the atlas manager while cleaning up, the + manager needs to be cleaned up after the textures, so + we post a deleteLater here at the very bottom so it gets + deferred deleted last. + + Another alternative would be to use a QPointer in + QSGAtlasTexture::Texture, but this seemed simpler. + */ + m_atlasManager->invalidate(); + m_atlasManager->deleteLater(); + m_atlasManager = nullptr; + + // The following piece of code will read/write to the font engine's caches, + // potentially from different threads. However, this is safe because this + // code is only called from QQuickWindow's shutdown which is called + // only when the GUI is blocked, and multiple threads will call it in + // sequence. (see qsgdefaultglyphnode_p.cpp's init()) + for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(), + end = m_fontEnginesToClean.constEnd(); it != end; ++it) { + (*it)->clearGlyphCache(m_gl); + if (!(*it)->ref.deref()) + delete *it; + } + m_fontEnginesToClean.clear(); + + delete m_depthStencilManager; + m_depthStencilManager = 0; + + delete m_distanceFieldCacheManager; + m_distanceFieldCacheManager = 0; + + if (m_gl->property(QSG_RENDERCONTEXT_PROPERTY) == QVariant::fromValue(this)) + m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant()); + m_gl = 0; + + QSGRenderContext::invalidate(); +} + +static QBasicMutex qsg_framerender_mutex; + +void QSGDefaultRenderContext::renderNextFrame(QSGRenderer *renderer, uint fboId) +{ + if (m_serializedRender) + qsg_framerender_mutex.lock(); + + renderer->renderScene(fboId); + + if (m_serializedRender) + qsg_framerender_mutex.unlock(); +} + +/*! + Returns a shared pointer to a depth stencil buffer that can be used with \a fbo. +*/ +QSharedPointer<QSGDepthStencilBuffer> QSGDefaultRenderContext::depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo) +{ + if (!m_gl) + return QSharedPointer<QSGDepthStencilBuffer>(); + QSGDepthStencilBufferManager *manager = depthStencilBufferManager(); + QSGDepthStencilBuffer::Format format; + format.size = fbo->size(); + format.samples = fbo->format().samples(); + format.attachments = QSGDepthStencilBuffer::DepthAttachment | QSGDepthStencilBuffer::StencilAttachment; + QSharedPointer<QSGDepthStencilBuffer> buffer = manager->bufferForFormat(format); + if (buffer.isNull()) { + buffer = QSharedPointer<QSGDepthStencilBuffer>(new QSGDefaultDepthStencilBuffer(m_gl, format)); + manager->insertBuffer(buffer); + } + return buffer; +} + +/*! + Returns a pointer to the context's depth/stencil buffer manager. This is useful for custom + implementations of \l depthStencilBufferForFbo(). +*/ +QSGDepthStencilBufferManager *QSGDefaultRenderContext::depthStencilBufferManager() +{ + if (!m_gl) + return 0; + if (!m_depthStencilManager) + m_depthStencilManager = new QSGDepthStencilBufferManager(m_gl); + return m_depthStencilManager; +} + +QSGTexture *QSGDefaultRenderContext::createTexture(const QImage &image, uint flags) const +{ + bool atlas = flags & CreateTexture_Atlas; + bool mipmap = flags & CreateTexture_Mipmap; + bool alpha = flags & CreateTexture_Alpha; + + // The atlas implementation is only supported from the render thread and + // does not support mipmaps. + if (!mipmap && atlas && openglContext() && QThread::currentThread() == openglContext()->thread()) { + QSGTexture *t = m_atlasManager->create(image, alpha); + if (t) + return t; + } + + QSGPlainTexture *texture = new QSGPlainTexture(); + texture->setImage(image); + if (texture->hasAlphaChannel() && !alpha) + texture->setHasAlphaChannel(false); + + return texture; +} + +QSGRenderer *QSGDefaultRenderContext::createRenderer() +{ + return new QSGBatchRenderer::Renderer(this); +} + +/*! + Compile \a shader, optionally using \a vertexCode and \a fragmentCode as + replacement for the source code supplied by \a shader. + + If \a vertexCode or \a fragmentCode is supplied, the caller is responsible + for setting up attribute bindings. + + \a material is supplied in case the implementation needs to take the + material flags into account. + */ +void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode, const char *fragmentCode) +{ + Q_UNUSED(material); + if (vertexCode || fragmentCode) { + Q_ASSERT_X((material->flags() & QSGMaterial::CustomCompileStep) == 0, + "QSGRenderContext::compile()", + "materials with custom compile step cannot have custom vertex/fragment code"); + QOpenGLShaderProgram *p = shader->program(); + p->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader()); + p->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader()); + p->link(); + if (!p->isLinked()) + qWarning() << "shader compilation failed:" << endl << p->log(); + } else { + shader->compile(); + } +} + +void QSGDefaultRenderContext::initializeShader(QSGMaterialShader *shader) +{ + shader->program()->bind(); + shader->initialize(); +} + +void QSGDefaultRenderContext::setAttachToGLContext(bool attach) +{ + Q_ASSERT(!isValid()); + m_attachToGLContext = attach; +} + +QSGDefaultRenderContext *QSGDefaultRenderContext::from(QOpenGLContext *context) +{ + return qobject_cast<QSGDefaultRenderContext *>(context->property(QSG_RENDERCONTEXT_PROPERTY).value<QObject *>()); +} + +QT_END_NAMESPACE + + +QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font) +{ + if (!m_distanceFieldCacheManager) + m_distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager; + + QSGDistanceFieldGlyphCache *cache = m_distanceFieldCacheManager->cache(font); + if (!cache) { + cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font); + m_distanceFieldCacheManager->insertCache(font, cache); + } + + return cache; +} diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h new file mode 100644 index 0000000000..bfb15b1eb9 --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGDEFAULTRENDERCONTEXT_H +#define QSGDEFAULTRENDERCONTEXT_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qsgcontext_p.h> +#include <QtQuick/private/qsgdepthstencilbuffer_p.h> + +QT_BEGIN_NAMESPACE + +class QOpenGLContext; +class QSGMaterialShader; +class QOpenGLFramebufferObject; + +namespace QSGAtlasTexture { + class Manager; +} + +class QSGDefaultRenderContext : public QSGRenderContext +{ + Q_OBJECT +public: + QSGDefaultRenderContext(QSGContext *context); + + QOpenGLContext *openglContext() const { return m_gl; } + bool isValid() const override { return m_gl; } + + void initialize(void *context) override; + void invalidate() override; + void renderNextFrame(QSGRenderer *renderer, uint fboId) override; + + QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font) override; + + virtual QSharedPointer<QSGDepthStencilBuffer> depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo); + QSGDepthStencilBufferManager *depthStencilBufferManager(); + + QSGTexture *createTexture(const QImage &image, uint flags) const override; + QSGRenderer *createRenderer() override; + + virtual void compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0); + virtual void initializeShader(QSGMaterialShader *shader); + + void setAttachToGLContext(bool attach); + + static QSGDefaultRenderContext *from(QOpenGLContext *context); + + bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; } + int maxTextureSize() const { return m_maxTextureSize; } + +protected: + QOpenGLContext *m_gl; + QSGDepthStencilBufferManager *m_depthStencilManager; + int m_maxTextureSize; + bool m_brokenIBOs; + bool m_serializedRender; + bool m_attachToGLContext; + QSGAtlasTexture::Manager *m_atlasManager; + + +}; + +QT_END_NAMESPACE + +#endif // QSGDEFAULTRENDERCONTEXT_H diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 1b0b1acc0e..3d019eab72 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -47,7 +47,6 @@ #include <QtCore/QLibraryInfo> #include <QtCore/private/qabstractanimation_p.h> -#include <QtGui/QOpenGLContext> #include <QtGui/QOffscreenSurface> #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> @@ -59,7 +58,11 @@ #include <QtQuick/private/qsgcontext_p.h> #include <private/qquickprofiler_p.h> -#include <private/qquickshadereffectnode_p.h> +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLContext> +# include <private/qsgdefaultrendercontext_p.h> +# include <private/qquickshadereffectnode_p.h> +#endif #ifdef Q_OS_WIN # include <QtCore/qt_windows.h> @@ -69,7 +72,7 @@ QT_BEGIN_NAMESPACE extern bool qsg_useConsistentTiming(); extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); - +#ifndef QT_NO_OPENGL /*! expectations for this manager to work: - one opengl context to render multiple windows @@ -81,7 +84,7 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP); DEFINE_BOOL_CONFIG_OPTION(qmlForceThreadedRenderer, QML_FORCE_THREADED_RENDERER); // Might trigger graphics driver threading bugs, use at own risk - +#endif QSGRenderLoop *QSGRenderLoop::s_instance = 0; QSGRenderLoop::~QSGRenderLoop() @@ -113,17 +116,20 @@ void QSGRenderLoop::cleanup() */ void QSGRenderLoop::postJob(QQuickWindow *window, QRunnable *job) { - Q_ASSERT(window); Q_ASSERT(job); - +#ifndef QT_NO_OPENGL + Q_ASSERT(window); if (window->openglContext()) { window->openglContext()->makeCurrent(window); job->run(); } - +#else + Q_UNUSED(window) + job->run(); +#endif delete job; } - +#ifndef QT_NO_OPENGL class QSGGuiThreadRenderLoop : public QSGRenderLoop { Q_OBJECT @@ -164,7 +170,7 @@ public: QImage grabContent; }; - +#endif QSGRenderLoop *QSGRenderLoop::instance() { if (!s_instance) { @@ -174,7 +180,7 @@ QSGRenderLoop *QSGRenderLoop::instance() const_cast<QLoggingCategory &>(QSG_LOG_INFO()).setEnabled(QtDebugMsg, true); s_instance = QSGContext::createWindowManager(); - +#ifndef QT_NO_OPENGL if (!s_instance) { enum RenderLoopType { @@ -226,9 +232,10 @@ QSGRenderLoop *QSGRenderLoop::instance() break; } } - +#endif qAddPostRoutine(QSGRenderLoop::cleanup); } + return s_instance; } @@ -263,7 +270,7 @@ void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window, if (!signalEmitted) qFatal("%s", qPrintable(untranslatedMessage)); } - +#ifndef QT_NO_OPENGL QSGGuiThreadRenderLoop::QSGGuiThreadRenderLoop() : gl(0) { @@ -358,8 +365,10 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) cd->fireOpenGLContextCreated(gl); current = gl->makeCurrent(window); } - if (current) - cd->context->initialize(gl); + if (current) { + auto openglRenderContext = static_cast<QSGDefaultRenderContext *>(cd->context); + openglRenderContext->initialize(gl); + } } else { current = gl->makeCurrent(window); } @@ -480,6 +489,8 @@ void QSGGuiThreadRenderLoop::handleUpdateRequest(QQuickWindow *window) renderWindow(window); } +#endif + #include "qsgrenderloop.moc" QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 7c3405b715..608afcff10 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -64,6 +64,7 @@ #include <private/qqmldebugconnector_p.h> #include <private/qquickshadereffectnode_p.h> +#include <private/qsgdefaultrendercontext_p.h> /* Overall design: @@ -268,7 +269,6 @@ public: QSGRenderThread(QSGThreadedRenderLoop *w, QSGRenderContext *renderContext) : wm(w) , gl(0) - , sgrc(renderContext) , animatorDriver(0) , pendingUpdate(0) , sleeping(false) @@ -277,6 +277,7 @@ public: , window(0) , stopEventProcessing(false) { + sgrc = static_cast<QSGDefaultRenderContext *>(renderContext); #if defined(Q_OS_QNX) && !defined(Q_OS_BLACKBERRY) && defined(Q_PROCESSOR_X86) // The SDP 6.6.0 x86 MESA driver requires a larger stack than the default. setStackSize(1024 * 1024); @@ -325,7 +326,7 @@ public: QSGThreadedRenderLoop *wm; QOpenGLContext *gl; - QSGRenderContext *sgrc; + QSGDefaultRenderContext *sgrc; QAnimationDriver *animatorDriver; diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 901fbbec43..84423a8cfc 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -48,6 +48,7 @@ #include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qsgdefaultrendercontext_p.h> #include <QtQuick/QQuickWindow> @@ -78,7 +79,7 @@ QSGWindowsRenderLoop::QSGWindowsRenderLoop() , m_updateTimer(0) , m_animationTimer(0) { - m_rc = m_sg->createRenderContext(); + m_rc = static_cast<QSGDefaultRenderContext *>(m_sg->createRenderContext()); m_animationDriver = m_sg->createAnimationDriver(m_sg); m_animationDriver->install(); @@ -341,6 +342,11 @@ void QSGWindowsRenderLoop::maybeUpdate(QQuickWindow *window) maybePostUpdateTimer(); } +QSGRenderContext *QSGWindowsRenderLoop::createRenderContext(QSGContext *) const +{ + return m_rc; +} + bool QSGWindowsRenderLoop::event(QEvent *event) { switch (event->type()) { diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h index ad7986035f..9e5d7f04d3 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h +++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QSGRenderContext; +class QSGDefaultRenderContext; class QSGWindowsRenderLoop : public QSGRenderLoop { @@ -83,7 +84,7 @@ public: QAnimationDriver *animationDriver() const { return m_animationDriver; } QSGContext *sceneGraphContext() const { return m_sg; } - QSGRenderContext *createRenderContext(QSGContext *) const { return m_rc; } + QSGRenderContext *createRenderContext(QSGContext *) const; void releaseResources(QQuickWindow *) { } @@ -113,7 +114,7 @@ private: QOpenGLContext *m_gl; QSGContext *m_sg; - QSGRenderContext *m_rc; + QSGDefaultRenderContext *m_rc; QAnimationDriver *m_animationDriver; diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index 84cc2ba135..79971a2b0d 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -5,9 +5,9 @@ # Core API HEADERS += \ - $$PWD/coreapi/qsgbatchrenderer_p.h \ $$PWD/coreapi/qsggeometry.h \ $$PWD/coreapi/qsgmaterial.h \ + $$PWD/coreapi/qsgmaterialshader_p.h \ $$PWD/coreapi/qsgnode.h \ $$PWD/coreapi/qsgnode_p.h \ $$PWD/coreapi/qsgnodeupdater_p.h \ @@ -15,159 +15,189 @@ HEADERS += \ $$PWD/coreapi/qsgabstractrenderer_p.h \ $$PWD/coreapi/qsgrenderer_p.h \ $$PWD/coreapi/qsgrendernode_p.h \ - $$PWD/coreapi/qsggeometry_p.h \ - $$PWD/coreapi/qsgmaterialshader_p.h + $$PWD/coreapi/qsggeometry_p.h SOURCES += \ $$PWD/coreapi/qsgabstractrenderer.cpp \ - $$PWD/coreapi/qsgbatchrenderer.cpp \ $$PWD/coreapi/qsggeometry.cpp \ $$PWD/coreapi/qsgmaterial.cpp \ $$PWD/coreapi/qsgnode.cpp \ $$PWD/coreapi/qsgnodeupdater.cpp \ $$PWD/coreapi/qsgrenderer.cpp \ - $$PWD/coreapi/qsgrendernode.cpp \ - $$PWD/coreapi/qsgshaderrewriter.cpp + $$PWD/coreapi/qsgrendernode.cpp + +contains(QT_CONFIG, opengl(es1|es2)?) { + HEADERS += \ + $$PWD/coreapi/qsgbatchrenderer_p.h + SOURCES += \ + $$PWD/coreapi/qsgbatchrenderer.cpp \ + $$PWD/coreapi/qsgshaderrewriter.cpp +} # Util API HEADERS += \ $$PWD/util/qsgareaallocator_p.h \ - $$PWD/util/qsgatlastexture_p.h \ - $$PWD/util/qsgdepthstencilbuffer_p.h \ $$PWD/util/qsgengine.h \ $$PWD/util/qsgengine_p.h \ - $$PWD/util/qsgflatcolormaterial.h \ - $$PWD/util/qsgsimplematerial.h \ $$PWD/util/qsgsimplerectnode.h \ $$PWD/util/qsgsimpletexturenode.h \ - $$PWD/util/qsgtexturematerial.h \ - $$PWD/util/qsgtexturematerial_p.h \ - $$PWD/util/qsgvertexcolormaterial.h \ $$PWD/util/qsgtexture.h \ $$PWD/util/qsgtexture_p.h \ $$PWD/util/qsgtextureprovider.h \ - $$PWD/util/qsgdefaultpainternode_p.h \ $$PWD/util/qsgdistancefieldutil_p.h \ - $$PWD/util/qsgshadersourcebuilder_p.h + $$PWD/util/qsgflatcolormaterial.h \ + $$PWD/util/qsgsimplematerial.h \ + $$PWD/util/qsgtexturematerial.h \ + $$PWD/util/qsgtexturematerial_p.h \ + $$PWD/util/qsgvertexcolormaterial.h SOURCES += \ $$PWD/util/qsgareaallocator.cpp \ - $$PWD/util/qsgatlastexture.cpp \ - $$PWD/util/qsgdepthstencilbuffer.cpp \ $$PWD/util/qsgengine.cpp \ - $$PWD/util/qsgflatcolormaterial.cpp \ $$PWD/util/qsgsimplerectnode.cpp \ $$PWD/util/qsgsimpletexturenode.cpp \ - $$PWD/util/qsgtexturematerial.cpp \ - $$PWD/util/qsgvertexcolormaterial.cpp \ $$PWD/util/qsgtexture.cpp \ $$PWD/util/qsgtextureprovider.cpp \ - $$PWD/util/qsgdefaultpainternode.cpp \ $$PWD/util/qsgdistancefieldutil.cpp \ + $$PWD/util/qsgflatcolormaterial.cpp \ $$PWD/util/qsgsimplematerial.cpp \ - $$PWD/util/qsgshadersourcebuilder.cpp + $$PWD/util/qsgtexturematerial.cpp \ + $$PWD/util/qsgvertexcolormaterial.cpp +contains(QT_CONFIG, opengl(es1|es2)?) { + HEADERS += \ + $$PWD/util/qsgdepthstencilbuffer_p.h \ + $$PWD/util/qsgshadersourcebuilder_p.h \ + $$PWD/util/qsgatlastexture_p.h + SOURCES += \ + $$PWD/util/qsgdepthstencilbuffer.cpp \ + $$PWD/util/qsgatlastexture.cpp \ + $$PWD/util/qsgshadersourcebuilder.cpp +} + # QML / Adaptations API HEADERS += \ $$PWD/qsgadaptationlayer_p.h \ $$PWD/qsgcontext_p.h \ $$PWD/qsgcontextplugin_p.h \ - $$PWD/qsgdefaultglyphnode_p.h \ - $$PWD/qsgdefaultdistancefieldglyphcache_p.h \ - $$PWD/qsgdistancefieldglyphnode_p.h \ - $$PWD/qsgdistancefieldglyphnode_p_p.h \ - $$PWD/qsgdefaultglyphnode_p_p.h \ - $$PWD/qsgdefaultimagenode_p.h \ - $$PWD/qsgdefaultrectanglenode_p.h \ - $$PWD/qsgrenderloop_p.h \ - $$PWD/qsgthreadedrenderloop_p.h \ - $$PWD/qsgwindowsrenderloop_p.h \ - $$PWD/qsgdefaultlayer_p.h + $$PWD/qsgbasicrectanglenode_p.h \ + $$PWD/qsgbasicimagenode_p.h \ + $$PWD/qsgbasicglyphnode_p.h \ + $$PWD/qsgrenderloop_p.h SOURCES += \ $$PWD/qsgadaptationlayer.cpp \ $$PWD/qsgcontext.cpp \ $$PWD/qsgcontextplugin.cpp \ - $$PWD/qsgdefaultglyphnode.cpp \ - $$PWD/qsgdefaultglyphnode_p.cpp \ - $$PWD/qsgdefaultdistancefieldglyphcache.cpp \ - $$PWD/qsgdistancefieldglyphnode.cpp \ - $$PWD/qsgdistancefieldglyphnode_p.cpp \ - $$PWD/qsgdefaultimagenode.cpp \ - $$PWD/qsgdefaultrectanglenode.cpp \ - $$PWD/qsgrenderloop.cpp \ - $$PWD/qsgthreadedrenderloop.cpp \ - $$PWD/qsgwindowsrenderloop.cpp \ - $$PWD/qsgdefaultlayer.cpp + $$PWD/qsgbasicrectanglenode.cpp \ + $$PWD/qsgbasicimagenode.cpp \ + $$PWD/qsgbasicglyphnode.cpp \ + $$PWD/qsgrenderloop.cpp + +contains(QT_CONFIG, opengl(es1|es2)?) { + SOURCES += \ + $$PWD/qsgdefaultglyphnode.cpp \ + $$PWD/qsgdefaultglyphnode_p.cpp \ + $$PWD/qsgdefaultdistancefieldglyphcache.cpp \ + $$PWD/qsgdistancefieldglyphnode.cpp \ + $$PWD/qsgdistancefieldglyphnode_p.cpp \ + $$PWD/qsgdefaultimagenode.cpp \ + $$PWD/qsgdefaultrectanglenode.cpp \ + $$PWD/qsgdefaultrendercontext.cpp \ + $$PWD/qsgdefaultcontext.cpp \ + $$PWD/util/qsgdefaultpainternode.cpp \ + $$PWD/qsgdefaultlayer.cpp \ + $$PWD/qsgthreadedrenderloop.cpp \ + $$PWD/qsgwindowsrenderloop.cpp + HEADERS += \ + $$PWD/qsgdefaultglyphnode_p.h \ + $$PWD/qsgdefaultdistancefieldglyphcache_p.h \ + $$PWD/qsgdistancefieldglyphnode_p.h \ + $$PWD/qsgdistancefieldglyphnode_p_p.h \ + $$PWD/qsgdefaultglyphnode_p_p.h \ + $$PWD/qsgdefaultimagenode_p.h \ + $$PWD/qsgdefaultrectanglenode_p.h \ + $$PWD/qsgdefaultrendercontext_p.h \ + $$PWD/qsgdefaultcontext_p.h \ + $$PWD/util/qsgdefaultpainternode_p.h \ + $$PWD/qsgdefaultlayer_p.h \ + $$PWD/qsgthreadedrenderloop_p.h \ + $$PWD/qsgwindowsrenderloop_p.h +} + +# Built-in, non-plugin-based adaptations +include(adaptations/adaptations.pri) RESOURCES += \ $$PWD/scenegraph.qrc -OTHER_FILES += \ - $$PWD/shaders/24bittextmask.frag \ - $$PWD/shaders/8bittextmask.frag \ - $$PWD/shaders/distancefieldoutlinetext.frag \ - $$PWD/shaders/distancefieldshiftedtext.frag \ - $$PWD/shaders/distancefieldshiftedtext.vert \ - $$PWD/shaders/distancefieldtext.frag \ - $$PWD/shaders/distancefieldtext.vert \ - $$PWD/shaders/flatcolor.frag \ - $$PWD/shaders/flatcolor.vert \ - $$PWD/shaders/hiqsubpixeldistancefieldtext.frag \ - $$PWD/shaders/hiqsubpixeldistancefieldtext.vert \ - $$PWD/shaders/loqsubpixeldistancefieldtext.frag \ - $$PWD/shaders/loqsubpixeldistancefieldtext.vert \ - $$PWD/shaders/opaquetexture.frag \ - $$PWD/shaders/opaquetexture.vert \ - $$PWD/shaders/outlinedtext.frag \ - $$PWD/shaders/outlinedtext.vert \ - $$PWD/shaders/rendernode.frag \ - $$PWD/shaders/rendernode.vert \ - $$PWD/shaders/smoothcolor.frag \ - $$PWD/shaders/smoothcolor.vert \ - $$PWD/shaders/smoothtexture.frag \ - $$PWD/shaders/smoothtexture.vert \ - $$PWD/shaders/stencilclip.frag \ - $$PWD/shaders/stencilclip.vert \ - $$PWD/shaders/styledtext.frag \ - $$PWD/shaders/styledtext.vert \ - $$PWD/shaders/textmask.frag \ - $$PWD/shaders/textmask.vert \ - $$PWD/shaders/texture.frag \ - $$PWD/shaders/vertexcolor.frag \ - $$PWD/shaders/vertexcolor.vert \ - $$PWD/shaders/24bittextmask_core.frag \ - $$PWD/shaders/8bittextmask_core.frag \ - $$PWD/shaders/distancefieldoutlinetext_core.frag \ - $$PWD/shaders/distancefieldshiftedtext_core.frag \ - $$PWD/shaders/distancefieldshiftedtext_core.vert \ - $$PWD/shaders/distancefieldtext_core.frag \ - $$PWD/shaders/distancefieldtext_core.vert \ - $$PWD/shaders/flatcolor_core.frag \ - $$PWD/shaders/flatcolor_core.vert \ - $$PWD/shaders/hiqsubpixeldistancefieldtext_core.frag \ - $$PWD/shaders/hiqsubpixeldistancefieldtext_core.vert \ - $$PWD/shaders/loqsubpixeldistancefieldtext_core.frag \ - $$PWD/shaders/loqsubpixeldistancefieldtext_core.vert \ - $$PWD/shaders/opaquetexture_core.frag \ - $$PWD/shaders/opaquetexture_core.vert \ - $$PWD/shaders/outlinedtext_core.frag \ - $$PWD/shaders/outlinedtext_core.vert \ - $$PWD/shaders/rendernode_core.frag \ - $$PWD/shaders/rendernode_core.vert \ - $$PWD/shaders/smoothcolor_core.frag \ - $$PWD/shaders/smoothcolor_core.vert \ - $$PWD/shaders/smoothtexture_core.frag \ - $$PWD/shaders/smoothtexture_core.vert \ - $$PWD/shaders/stencilclip_core.frag \ - $$PWD/shaders/stencilclip_core.vert \ - $$PWD/shaders/styledtext_core.frag \ - $$PWD/shaders/styledtext_core.vert \ - $$PWD/shaders/textmask_core.frag \ - $$PWD/shaders/textmask_core.vert \ - $$PWD/shaders/texture_core.frag \ - $$PWD/shaders/vertexcolor_core.frag \ - $$PWD/shaders/vertexcolor_core.vert \ - scenegraph/shaders/visualization.frag \ - scenegraph/shaders/visualization.vert - +# OpenGL Shaders +contains(QT_CONFIG, opengl(es1|es2)?) { + OTHER_FILES += \ + $$PWD/shaders/24bittextmask.frag \ + $$PWD/shaders/8bittextmask.frag \ + $$PWD/shaders/distancefieldoutlinetext.frag \ + $$PWD/shaders/distancefieldshiftedtext.frag \ + $$PWD/shaders/distancefieldshiftedtext.vert \ + $$PWD/shaders/distancefieldtext.frag \ + $$PWD/shaders/distancefieldtext.vert \ + $$PWD/shaders/flatcolor.frag \ + $$PWD/shaders/flatcolor.vert \ + $$PWD/shaders/hiqsubpixeldistancefieldtext.frag \ + $$PWD/shaders/hiqsubpixeldistancefieldtext.vert \ + $$PWD/shaders/loqsubpixeldistancefieldtext.frag \ + $$PWD/shaders/loqsubpixeldistancefieldtext.vert \ + $$PWD/shaders/opaquetexture.frag \ + $$PWD/shaders/opaquetexture.vert \ + $$PWD/shaders/outlinedtext.frag \ + $$PWD/shaders/outlinedtext.vert \ + $$PWD/shaders/rendernode.frag \ + $$PWD/shaders/rendernode.vert \ + $$PWD/shaders/smoothcolor.frag \ + $$PWD/shaders/smoothcolor.vert \ + $$PWD/shaders/smoothtexture.frag \ + $$PWD/shaders/smoothtexture.vert \ + $$PWD/shaders/stencilclip.frag \ + $$PWD/shaders/stencilclip.vert \ + $$PWD/shaders/styledtext.frag \ + $$PWD/shaders/styledtext.vert \ + $$PWD/shaders/textmask.frag \ + $$PWD/shaders/textmask.vert \ + $$PWD/shaders/texture.frag \ + $$PWD/shaders/vertexcolor.frag \ + $$PWD/shaders/vertexcolor.vert \ + $$PWD/shaders/24bittextmask_core.frag \ + $$PWD/shaders/8bittextmask_core.frag \ + $$PWD/shaders/distancefieldoutlinetext_core.frag \ + $$PWD/shaders/distancefieldshiftedtext_core.frag \ + $$PWD/shaders/distancefieldshiftedtext_core.vert \ + $$PWD/shaders/distancefieldtext_core.frag \ + $$PWD/shaders/distancefieldtext_core.vert \ + $$PWD/shaders/flatcolor_core.frag \ + $$PWD/shaders/flatcolor_core.vert \ + $$PWD/shaders/hiqsubpixeldistancefieldtext_core.frag \ + $$PWD/shaders/hiqsubpixeldistancefieldtext_core.vert \ + $$PWD/shaders/loqsubpixeldistancefieldtext_core.frag \ + $$PWD/shaders/loqsubpixeldistancefieldtext_core.vert \ + $$PWD/shaders/opaquetexture_core.frag \ + $$PWD/shaders/opaquetexture_core.vert \ + $$PWD/shaders/outlinedtext_core.frag \ + $$PWD/shaders/outlinedtext_core.vert \ + $$PWD/shaders/rendernode_core.frag \ + $$PWD/shaders/rendernode_core.vert \ + $$PWD/shaders/smoothcolor_core.frag \ + $$PWD/shaders/smoothcolor_core.vert \ + $$PWD/shaders/smoothtexture_core.frag \ + $$PWD/shaders/smoothtexture_core.vert \ + $$PWD/shaders/stencilclip_core.frag \ + $$PWD/shaders/stencilclip_core.vert \ + $$PWD/shaders/styledtext_core.frag \ + $$PWD/shaders/styledtext_core.vert \ + $$PWD/shaders/textmask_core.frag \ + $$PWD/shaders/textmask_core.vert \ + $$PWD/shaders/texture_core.frag \ + $$PWD/shaders/vertexcolor_core.frag \ + $$PWD/shaders/vertexcolor_core.vert \ + $$PWD/shaders/visualization.frag \ + $$PWD/shaders/visualization.vert +} diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index 68dc813933..06c4129a33 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -44,6 +44,7 @@ #include <QtCore/QtMath> #include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFunctions> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> #include <QtGui/QSurface> diff --git a/src/quick/scenegraph/util/qsgatlastexture_p.h b/src/quick/scenegraph/util/qsgatlastexture_p.h index c6f1e72a4d..da5acb3fea 100644 --- a/src/quick/scenegraph/util/qsgatlastexture_p.h +++ b/src/quick/scenegraph/util/qsgatlastexture_p.h @@ -104,17 +104,17 @@ public: QSize size() const { return m_size; } - GLuint internalFormat() const { return m_internalFormat; } - GLuint externalFormat() const { return m_externalFormat; } + uint internalFormat() const { return m_internalFormat; } + uint externalFormat() const { return m_externalFormat; } private: QSGAreaAllocator m_allocator; - GLuint m_texture_id; + unsigned int m_texture_id; QSize m_size; QList<Texture *> m_pending_uploads; - GLuint m_internalFormat; - GLuint m_externalFormat; + uint m_internalFormat; + uint m_externalFormat; uint m_allocated : 1; uint m_use_bgra_fallback: 1; diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp index 2deb993a6e..4dd60c76f5 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp @@ -41,6 +41,7 @@ #include <QtQuick/private/qquickpainteditem_p.h> +#include <QtQuick/private/qsgdefaultrendercontext_p.h> #include <QtQuick/private/qsgcontext_p.h> #include <private/qopenglextensions_p.h> #include <qopenglframebufferobject.h> @@ -96,7 +97,7 @@ QSGDefaultPainterNode::QSGDefaultPainterNode(QQuickPaintedItem *item) , m_dirtyRenderTarget(false) , m_dirtyTexture(false) { - m_context = static_cast<QQuickPaintedItemPrivate *>(QObjectPrivate::get(item))->sceneGraphRenderContext(); + m_context = static_cast<QSGDefaultRenderContext *>(static_cast<QQuickPaintedItemPrivate *>(QObjectPrivate::get(item))->sceneGraphRenderContext()); setMaterial(&m_materialO); setOpaqueMaterial(&m_material); diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h index 3cabe01511..069ef155b1 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h +++ b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE class QOpenGLFramebufferObject; class QOpenGLPaintDevice; +class QSGDefaultRenderContext; class Q_QUICK_PRIVATE_EXPORT QSGPainterTexture : public QSGPlainTexture { @@ -127,7 +128,7 @@ private: void updateRenderTarget(); void updateFBOSize(); - QSGRenderContext *m_context; + QSGDefaultRenderContext *m_context; QQuickPaintedItem::RenderTarget m_preferredRenderTarget; QQuickPaintedItem::RenderTarget m_actualRenderTarget; diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp index 5eb6a6f593..65a6bcd52c 100644 --- a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp +++ b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp @@ -40,7 +40,9 @@ #include "qsgdistancefieldutil_p.h" #include <private/qsgadaptationlayer_p.h> -#include <QtGui/private/qopenglengineshadersource_p.h> +#ifndef QT_NO_OPENGL +# include <QtGui/private/qopenglengineshadersource_p.h> +#endif #include <QtQuick/private/qsgcontext_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp index 1ef98d222d..da7a65cfec 100644 --- a/src/quick/scenegraph/util/qsgengine.cpp +++ b/src/quick/scenegraph/util/qsgengine.cpp @@ -44,6 +44,11 @@ #include <private/qsgrenderer_p.h> #include <private/qsgtexture_p.h> +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLContext> +# include <private/qsgdefaultrendercontext_p.h> +#endif + QT_BEGIN_NAMESPACE @@ -83,7 +88,7 @@ QT_BEGIN_NAMESPACE QSGEnginePrivate::QSGEnginePrivate() : sgContext(QSGContext::createDefaultContext()) - , sgRenderContext(new QSGRenderContext(sgContext.data())) + , sgRenderContext(sgContext.data()->createRenderContext()) { } @@ -110,17 +115,23 @@ QSGEngine::~QSGEngine() */ void QSGEngine::initialize(QOpenGLContext *context) { +#ifndef QT_NO_OPENGL Q_D(QSGEngine); if (QOpenGLContext::currentContext() != context) { qWarning("WARNING: The context must be current before calling QSGEngine::initialize."); return; } - if (!d->sgRenderContext->isValid()) { - d->sgRenderContext->setAttachToGLContext(false); - d->sgRenderContext->initialize(context); + auto openGLRenderContext = static_cast<QSGDefaultRenderContext *>(d->sgRenderContext.data()); + + if (openGLRenderContext != nullptr && !openGLRenderContext->isValid()) { + openGLRenderContext->setAttachToGLContext(false); + openGLRenderContext->initialize(context); connect(context, &QOpenGLContext::aboutToBeDestroyed, this, &QSGEngine::invalidate); } +#else + Q_UNUSED(context) +#endif } /*! diff --git a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp index 836b5759a2..b9986c3d11 100644 --- a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp @@ -39,8 +39,9 @@ #include "qsgflatcolormaterial.h" #include <private/qsgmaterialshader_p.h> - -#include <qopenglshaderprogram.h> +#ifndef QT_NO_OPENGL +# include <qopenglshaderprogram.h> +#endif QT_BEGIN_NAMESPACE @@ -66,14 +67,16 @@ QSGMaterialType FlatColorMaterialShader::type; FlatColorMaterialShader::FlatColorMaterialShader() : QSGMaterialShader(*new QSGMaterialShaderPrivate) { +#ifndef QT_NO_OPENGL setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/flatcolor.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/flatcolor.frag")); +#endif } void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { +#ifndef QT_NO_OPENGL Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - QSGFlatColorMaterial *oldMaterial = static_cast<QSGFlatColorMaterial *>(oldEffect); QSGFlatColorMaterial *newMaterial = static_cast<QSGFlatColorMaterial *>(newEffect); @@ -90,6 +93,11 @@ void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial if (state.isMatrixDirty()) program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +#else + Q_UNUSED(state) + Q_UNUSED(newEffect) + Q_UNUSED(oldEffect) +#endif } char const *const *FlatColorMaterialShader::attributeNames() const @@ -100,8 +108,10 @@ char const *const *FlatColorMaterialShader::attributeNames() const void FlatColorMaterialShader::initialize() { +#ifndef QT_NO_OPENGL m_matrix_id = program()->uniformLocation("matrix"); m_color_id = program()->uniformLocation("color"); +#endif } diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 9b9c77dce4..1ec1db5ab5 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qsgtexture_p.h" -#include <qopenglfunctions.h> #include <QtQuick/private/qsgcontext_p.h> #include <qthread.h> #include <qmath.h> @@ -46,9 +45,12 @@ #include <private/qqmlglobal_p.h> #include <QtGui/qguiapplication.h> #include <QtGui/qpa/qplatformnativeinterface.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglfunctions.h> - +#ifndef QT_NO_OPENGL +# include <qopenglfunctions.h> +# include <QtGui/qopenglcontext.h> +# include <QtGui/qopenglfunctions.h> +# include <private/qsgdefaultrendercontext_p.h> +#endif #include <private/qsgmaterialshader_p.h> #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && !defined(__UCLIBC__) @@ -278,6 +280,7 @@ Q_GLOBAL_STATIC(QMutex, qsg_valid_texture_mutex) bool qsg_safeguard_texture(QSGTexture *texture) { +#ifndef QT_NO_OPENGL QMutexLocker locker(qsg_valid_texture_mutex()); if (!qsg_valid_texture_set()->contains(texture)) { qWarning() << "Invalid texture accessed:" << (void *) texture; @@ -285,6 +288,7 @@ bool qsg_safeguard_texture(QSGTexture *texture) QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, 0); return false; } +#endif return true; } #endif @@ -517,6 +521,7 @@ QSGTexture::WrapMode QSGTexture::verticalWrapMode() const */ void QSGTexture::updateBindOptions(bool force) { +#ifndef QT_NO_OPENGL Q_D(QSGTexture); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); force |= isAtlasTexture(); @@ -551,6 +556,9 @@ void QSGTexture::updateBindOptions(bool force) funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, d->verticalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); d->wrapChanged = false; } +#else + Q_UNUSED(force) +#endif } QSGPlainTexture::QSGPlainTexture() @@ -568,8 +576,10 @@ QSGPlainTexture::QSGPlainTexture() QSGPlainTexture::~QSGPlainTexture() { +#ifndef QT_NO_OPENGL if (m_texture_id && m_owns_texture && QOpenGLContext::currentContext()) QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); +#endif } void qsg_swizzleBGRAToRGBA(QImage *image) @@ -601,8 +611,10 @@ int QSGPlainTexture::textureId() const // or ~QSGPlainTexture so just keep it minimal here. return 0; } else if (m_texture_id == 0){ +#ifndef QT_NO_OPENGL // Generate a texture id for use later and return it. QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<QSGPlainTexture *>(this)->m_texture_id); +#endif return m_texture_id; } } @@ -611,8 +623,10 @@ int QSGPlainTexture::textureId() const void QSGPlainTexture::setTextureId(int id) { +#ifndef QT_NO_OPENGL if (m_texture_id && m_owns_texture) QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); +#endif m_texture_id = id; m_dirty_texture = false; @@ -623,6 +637,7 @@ void QSGPlainTexture::setTextureId(int id) void QSGPlainTexture::bind() { +#ifndef QT_NO_OPENGL QOpenGLContext *context = QOpenGLContext::currentContext(); QOpenGLFunctions *funcs = context->functions(); if (!m_dirty_texture) { @@ -684,7 +699,7 @@ void QSGPlainTexture::bind() // based on QSGTexture::textureSize which is updated after this, so that // should be ok. int max; - if (QSGRenderContext *rc = QSGRenderContext::from(context)) + if (auto rc = QSGDefaultRenderContext::from(context)) max = rc->maxTextureSize(); else funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); @@ -789,6 +804,7 @@ void QSGPlainTexture::bind() m_dirty_bind_options = false; if (!m_retain_image) m_image = QImage(); +#endif } diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h index 5c358aecc3..a0d7eb41e3 100644 --- a/src/quick/scenegraph/util/qsgtexture_p.h +++ b/src/quick/scenegraph/util/qsgtexture_p.h @@ -53,9 +53,9 @@ #include <QtQuick/qtquickglobal.h> #include <private/qobject_p.h> - -#include <QtGui/qopengl.h> - +#ifndef QT_NO_OPENGL +# include <QtGui/qopengl.h> +#endif #include "qsgtexture.h" #include <QtQuick/private/qsgcontext_p.h> @@ -110,7 +110,7 @@ public: protected: QImage m_image; - GLuint m_texture_id; + uint m_texture_id; QSize m_texture_size; QRectF m_texture_rect; diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp index 66e87a77a8..12a1b474e3 100644 --- a/src/quick/scenegraph/util/qsgtexturematerial.cpp +++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp @@ -39,9 +39,10 @@ #include "qsgtexturematerial_p.h" #include "qsgtexture_p.h" - -#include <QtGui/qopenglshaderprogram.h> -#include <QtGui/qopenglfunctions.h> +#ifndef QT_NO_OPENGL +# include <QtGui/qopenglshaderprogram.h> +# include <QtGui/qopenglfunctions.h> +#endif QT_BEGIN_NAMESPACE @@ -56,8 +57,10 @@ QSGMaterialType QSGOpaqueTextureMaterialShader::type; QSGOpaqueTextureMaterialShader::QSGOpaqueTextureMaterialShader() : QSGMaterialShader() { +#ifndef QT_NO_OPENGL setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/opaquetexture.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/opaquetexture.frag")); +#endif } char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const @@ -68,7 +71,9 @@ char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const void QSGOpaqueTextureMaterialShader::initialize() { +#ifndef QT_NO_OPENGL m_matrix_id = program()->uniformLocation("qt_Matrix"); +#endif } void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) @@ -88,6 +93,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa t->setHorizontalWrapMode(tx->horizontalWrapMode()); t->setVerticalWrapMode(tx->verticalWrapMode()); +#ifndef QT_NO_OPENGL bool npotSupported = const_cast<QOpenGLContext *>(state.context()) ->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat); if (!npotSupported) { @@ -98,16 +104,17 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa t->setVerticalWrapMode(QSGTexture::ClampToEdge); } } - +#endif t->setMipmapFiltering(tx->mipmapFiltering()); if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId()) t->bind(); else t->updateBindOptions(); - +#ifndef QT_NO_OPENGL if (state.isMatrixDirty()) program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +#endif } @@ -362,22 +369,27 @@ QSGMaterialShader *QSGTextureMaterial::createShader() const QSGTextureMaterialShader::QSGTextureMaterialShader() : QSGOpaqueTextureMaterialShader() { +#ifndef QT_NO_OPENGL setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/texture.frag")); +#endif } void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); +#ifndef QT_NO_OPENGL if (state.isOpacityDirty()) program()->setUniformValue(m_opacity_id, state.opacity()); - +#endif QSGOpaqueTextureMaterialShader::updateState(state, newEffect, oldEffect); } void QSGTextureMaterialShader::initialize() { QSGOpaqueTextureMaterialShader::initialize(); +#ifndef QT_NO_OPENGL m_opacity_id = program()->uniformLocation("opacity"); +#endif } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp index 8e86b3906f..18de19b04e 100644 --- a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp @@ -38,9 +38,9 @@ ****************************************************************************/ #include "qsgvertexcolormaterial.h" - -#include <qopenglshaderprogram.h> - +#ifndef QT_NO_OPENGL +# include <qopenglshaderprogram.h> +#endif QT_BEGIN_NAMESPACE class QSGVertexColorMaterialShader : public QSGMaterialShader @@ -65,17 +65,23 @@ QSGMaterialType QSGVertexColorMaterialShader::type; QSGVertexColorMaterialShader::QSGVertexColorMaterialShader() : QSGMaterialShader() { +#ifndef QT_NO_OPENGL setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/vertexcolor.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/vertexcolor.frag")); +#endif } void QSGVertexColorMaterialShader::updateState(const RenderState &state, QSGMaterial * /*newEffect*/, QSGMaterial *) { +#ifndef QT_NO_OPENGL if (state.isOpacityDirty()) program()->setUniformValue(m_opacity_id, state.opacity()); if (state.isMatrixDirty()) program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +#else + Q_UNUSED(state) +#endif } char const *const *QSGVertexColorMaterialShader::attributeNames() const @@ -86,8 +92,10 @@ char const *const *QSGVertexColorMaterialShader::attributeNames() const void QSGVertexColorMaterialShader::initialize() { +#ifndef QT_NO_OPENGL m_matrix_id = program()->uniformLocation("matrix"); m_opacity_id = program()->uniformLocation("opacity"); +#endif } diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp index abae6321b0..100b7bd402 100644 --- a/src/quick/util/qquickanimator.cpp +++ b/src/quick/util/qquickanimator.cpp @@ -502,7 +502,7 @@ QQuickRotationAnimator::RotationDirection QQuickRotationAnimator::direction() co Q_D(const QQuickRotationAnimator); return d->direction; } - +#ifndef QT_NO_OPENGL /*! \qmltype UniformAnimator \instantiates QQuickUniformAnimator @@ -580,5 +580,6 @@ QQuickAnimatorJob *QQuickUniformAnimator::createJob() const job->setUniform(u.toLatin1()); return job; } +#endif QT_END_NAMESPACE diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h index c23aa0a7e9..f1e2d4e1d9 100644 --- a/src/quick/util/qquickanimator_p.h +++ b/src/quick/util/qquickanimator_p.h @@ -169,7 +169,7 @@ protected: QQuickAnimatorJob *createJob() const; QString propertyName() const { return QStringLiteral("rotation"); } }; - +#ifndef QT_NO_OPENGL class QQuickUniformAnimatorPrivate; class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimator : public QQuickAnimator { @@ -190,6 +190,7 @@ protected: QQuickAnimatorJob *createJob() const; QString propertyName() const; }; +#endif QT_END_NAMESPACE @@ -199,6 +200,7 @@ QML_DECLARE_TYPE(QQuickYAnimator) QML_DECLARE_TYPE(QQuickScaleAnimator) QML_DECLARE_TYPE(QQuickRotationAnimator) QML_DECLARE_TYPE(QQuickOpacityAnimator) +#ifndef QT_NO_OPENGL QML_DECLARE_TYPE(QQuickUniformAnimator) - +#endif #endif // QQUICKANIMATOR_P_H diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 8d5ecadab5..f0ecb8150a 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -43,8 +43,9 @@ #include "qquickanimator_p_p.h" #include <private/qquickwindow_p.h> #include <private/qquickitem_p.h> -#include <private/qquickshadereffectnode_p.h> - +#ifndef QT_NO_OPENGL +# include <private/qquickshadereffectnode_p.h> +#endif #include <private/qanimationgroupjob_p.h> #include <qcoreapplication.h> @@ -173,7 +174,7 @@ void QQuickAnimatorProxyJob::setWindow(QQuickWindow *window) } else if (!m_controller && m_job) { m_controller = QQuickWindowPrivate::get(window)->animationController; - if (window->openglContext()) + if (window->isSceneGraphInitialized()) readyToAnimate(); else connect(window, SIGNAL(sceneGraphInitialized()), this, SLOT(sceneGraphInitialized())); @@ -390,7 +391,6 @@ void QQuickXAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(!m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * progress(time); m_helper->dx = m_value; @@ -407,7 +407,6 @@ void QQuickYAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(!m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * progress(time); m_helper->dy = m_value; @@ -477,7 +476,6 @@ void QQuickOpacityAnimatorJob::updateCurrentTime(int time) { if (!m_controller || !m_opacityNode) return; - Q_ASSERT(!m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * progress(time); m_opacityNode->setOpacity(m_value); @@ -493,7 +491,6 @@ void QQuickScaleAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(!m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); m_value = m_from + (m_to - m_from) * progress(time); m_helper->scale = m_value; @@ -513,7 +510,6 @@ void QQuickRotationAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(!m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); float t = progress(time); @@ -546,6 +542,7 @@ void QQuickRotationAnimatorJob::writeBack() m_target->setRotation(value()); } +#ifndef QT_NO_OPENGL QQuickUniformAnimatorJob::QQuickUniformAnimatorJob() : m_node(0) , m_uniformIndex(-1) @@ -594,7 +591,6 @@ void QQuickUniformAnimatorJob::updateCurrentTime(int time) { if (!m_controller) return; - Q_ASSERT(!m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); if (!m_node || m_uniformIndex == -1 || m_uniformType == -1) return; @@ -615,5 +611,6 @@ void QQuickUniformAnimatorJob::writeBack() if (m_target) m_target->setProperty(m_uniform, value()); } +#endif QT_END_NAMESPACE diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index 2b910d3737..118487f937 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -277,7 +277,7 @@ public: private: QSGOpacityNode *m_opacityNode; }; - +#ifndef QT_NO_OPENGL class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimatorJob : public QQuickAnimatorJob { public: @@ -301,6 +301,7 @@ private: int m_uniformIndex : 8; int m_uniformType : 8; }; +#endif QT_END_NAMESPACE diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp index f5d11c6230..66994e22ba 100644 --- a/src/quick/util/qquickutilmodule.cpp +++ b/src/quick/util/qquickutilmodule.cpp @@ -107,8 +107,9 @@ void QQuickUtilModule::defineModule() qmlRegisterType<QQuickScaleAnimator>("QtQuick", 2, 2, "ScaleAnimator"); qmlRegisterType<QQuickRotationAnimator>("QtQuick", 2, 2, "RotationAnimator"); qmlRegisterType<QQuickOpacityAnimator>("QtQuick", 2, 2, "OpacityAnimator"); +#ifndef QT_NO_OPENGL qmlRegisterType<QQuickUniformAnimator>("QtQuick", 2, 2, "UniformAnimator"); - +#endif qmlRegisterType<QQuickStateOperation>(); qmlRegisterCustomType<QQuickPropertyChanges>("QtQuick",2,0,"PropertyChanges", new QQuickPropertyChangesParser); diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 3bce7827bc..0a10ec5e9c 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -57,6 +57,10 @@ #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformintegration.h> +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFunctions> +#include <QtGui/private/qopenglextensions_p.h> + #ifdef Q_OS_WIN # include <QtWidgets/QMessageBox> # include <QtCore/QLibraryInfo> diff --git a/src/src.pro b/src/src.pro index 385e4eb601..e3975083da 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,19 +1,18 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS += \ - qml + qml \ + quick \ + qmltest qtHaveModule(gui):contains(QT_CONFIG, opengl(es1|es2)?) { - SUBDIRS += \ - quick \ - qmltest \ - particles - + SUBDIRS += particles qtHaveModule(widgets): SUBDIRS += quickwidgets } SUBDIRS += \ plugins \ + doc \ imports \ qmldevtools diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 425e88b983..b72a43d742 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -2,16 +2,18 @@ TEMPLATE=subdirs SUBDIRS=\ qml \ quick \ - particles \ qmltest \ qmldevtools \ cmake \ installed_cmake \ toolsupport -qtHaveModule(widgets): SUBDIRS += quickwidgets +qtHaveModule(gui):contains(QT_CONFIG, opengl(es1|es2)?) { + SUBDIRS += particles + qtHaveModule(widgets): SUBDIRS += quickwidgets + +} qmldevtools.CONFIG = host_build installed_cmake.depends = cmake - diff --git a/tests/auto/quick/geometry/tst_geometry.cpp b/tests/auto/quick/geometry/tst_geometry.cpp index 8755e3a1d7..7988b6b515 100644 --- a/tests/auto/quick/geometry/tst_geometry.cpp +++ b/tests/auto/quick/geometry/tst_geometry.cpp @@ -126,9 +126,9 @@ void GeometryTest::testCustomGeometry() }; static QSGGeometry::Attribute attributes[] = { - { 0, 2, GL_FLOAT, 0, 0}, - { 1, 4, GL_UNSIGNED_BYTE, 0, 0}, - { 2, 4, GL_FLOAT, 0, 0}, + QSGGeometry::Attribute::create(0, 2, GL_FLOAT, false), + QSGGeometry::Attribute::create(1, 4, GL_UNSIGNED_BYTE, false), + QSGGeometry::Attribute::create(2, 4, GL_FLOAT, false) }; static QSGGeometry::AttributeSet set = { 4, 6 * sizeof(float) + 4 * sizeof(unsigned char), attributes }; diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp index 16c1174604..63e0aeb324 100644 --- a/tests/auto/quick/nodes/tst_nodestest.cpp +++ b/tests/auto/quick/nodes/tst_nodestest.cpp @@ -31,7 +31,6 @@ #include <QtGui/QOffscreenSurface> #include <QtGui/QOpenGLContext> - #include <QtQuick/qsgnode.h> #include <QtQuick/private/qsgbatchrenderer_p.h> #include <QtQuick/private/qsgnodeupdater_p.h> @@ -76,7 +75,7 @@ private Q_SLOTS: private: QOffscreenSurface *surface; QOpenGLContext *context; - QSGRenderContext *renderContext; + QSGDefaultRenderContext *renderContext; }; void NodesTest::initTestCase() @@ -91,7 +90,8 @@ void NodesTest::initTestCase() QVERIFY(context->create()); QVERIFY(context->makeCurrent(surface)); - renderContext = renderLoop->createRenderContext(renderLoop->sceneGraphContext()); + auto rc = renderLoop->createRenderContext(renderLoop->sceneGraphContext()); + renderContext = static_cast<QSGDefaultRenderContext *>(rc); QVERIFY(renderContext); renderContext->initialize(context); QVERIFY(renderContext->isValid()); @@ -110,7 +110,7 @@ void NodesTest::cleanupTestCase() class DummyRenderer : public QSGBatchRenderer::Renderer { public: - DummyRenderer(QSGRootNode *root, QSGRenderContext *renderContext) + DummyRenderer(QSGRootNode *root, QSGDefaultRenderContext *renderContext) : QSGBatchRenderer::Renderer(renderContext) , changedNode(0) , changedState(0) diff --git a/tests/manual/nodetypes/Animators.qml b/tests/manual/nodetypes/Animators.qml new file mode 100644 index 0000000000..7d8baf1cb8 --- /dev/null +++ b/tests/manual/nodetypes/Animators.qml @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 + +Item { + id: window + + Rectangle { + anchors.fill: parent + gradient: Gradient { + GradientStop { position: 0.0; color: "#14148c" } + GradientStop { position: 0.499; color: "#14aaff" } + GradientStop { position: 0.5; color: "#80c342" } + GradientStop { position: 1.0; color: "#006325" } + } + } + + SequentialAnimation { + id: plainAnim + SequentialAnimation { + ParallelAnimation { + PropertyAnimation { + property: "y" + target: smiley + from: smiley.minHeight + to: smiley.maxHeight + easing.type: Easing.OutExpo + duration: 300 + } + PropertyAnimation { + property: "scale" + target: shadow + from: 1 + to: 0.5 + easing.type: Easing.OutExpo + duration: 300 + } + } + ParallelAnimation { + PropertyAnimation { + property: "y" + target: smiley + from: smiley.maxHeight + to: smiley.minHeight + easing.type: Easing.OutBounce + duration: 1000 + } + PropertyAnimation { + property: "scale" + target: shadow + from: 0.5 + to: 1 + easing.type: Easing.OutBounce + duration: 1000 + } + } + } + running: false + } + + SequentialAnimation { + id: renderThreadAnim + SequentialAnimation { + ParallelAnimation { + YAnimator { + target: smiley + from: smiley.minHeight + to: smiley.maxHeight + easing.type: Easing.OutExpo + duration: 300 + } + ScaleAnimator { + target: shadow + from: 1 + to: 0.5 + easing.type: Easing.OutExpo + duration: 300 + } + } + ParallelAnimation { + YAnimator { + target: smiley + from: smiley.maxHeight + to: smiley.minHeight + easing.type: Easing.OutBounce + duration: 1000 + } + ScaleAnimator { + target: shadow + from: 0.5 + to: 1 + easing.type: Easing.OutBounce + duration: 1000 + } + } + } + running: false + } + + Image { + id: shadow + anchors.horizontalCenter: parent.horizontalCenter + y: smiley.minHeight + smiley.height + source: "qrc:/shadow.png" + } + + Image { + id: smiley + property int maxHeight: window.height / 3 + property int minHeight: 2 * window.height / 3 + + anchors.horizontalCenter: parent.horizontalCenter + y: minHeight + source: "qrc:/face-smile.png" + } + + Text { + text: "click left for plain animation, right for render thread Animators, middle to sleep for 2 sec on the main (gui) thread" + color: "white" + } + + Text { + text: plainAnim.running ? "NORMAL ANIMATION" : (renderThreadAnim.running ? "RENDER THREAD ANIMATION" : "NO ANIMATION") + color: "red" + font.pointSize: 20 + anchors.bottom: parent.bottom + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.AllButtons + onClicked: if (mouse.button === Qt.LeftButton) { + renderThreadAnim.running = false; + plainAnim.running = true; + } else if (mouse.button === Qt.RightButton) { + plainAnim.running = false; + renderThreadAnim.running = true; + } else if (mouse.button === Qt.MiddleButton) { + helper.sleep(2000); + } + } +} diff --git a/tests/manual/nodetypes/Images.qml b/tests/manual/nodetypes/Images.qml new file mode 100644 index 0000000000..7c1ba5345b --- /dev/null +++ b/tests/manual/nodetypes/Images.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.3 + +Item { + Rectangle { + width: 100 + height: 100 + anchors.centerIn: parent + color: "red" + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + } + + Image { + id: im + source: "qrc:/qt.png" + mipmap: true + + // changing the mipmap property results in the creation of a brand new + // texture resource. enable the following to test. +// Timer { +// interval: 2000 +// onTriggered: im.mipmap = false +// running: true +// } + + SequentialAnimation on scale { + loops: Animation.Infinite + NumberAnimation { + from: 1.0 + to: 4.0 + duration: 2000 + } + NumberAnimation { + from: 4.0 + to: 0.1 + duration: 3000 + } + NumberAnimation { + from: 0.1 + to: 1.0 + duration: 1000 + } + } + + Image { + anchors.centerIn: parent + source: "qrc:/face-smile.png" + } + } + + Image { + source: "qrc:/face-smile.png" + anchors.bottom: parent.bottom + anchors.right: parent.right + antialiasing: true + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + } +} diff --git a/tests/manual/nodetypes/Layers.qml b/tests/manual/nodetypes/Layers.qml new file mode 100644 index 0000000000..52c8fa8144 --- /dev/null +++ b/tests/manual/nodetypes/Layers.qml @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + Rectangle { + color: "lightGray" + anchors.fill: parent + anchors.margins: 10 + + Row { + anchors.fill: parent + anchors.margins: 10 + Rectangle { + color: "red" +// ColorAnimation on color { +// from: "black" +// to: "white" +// duration: 2000 +// loops: Animation.Infinite +// } + width: 300 + height: 100 + layer.enabled: true + Text { text: "this is in a layer, going through an offscreen render target" } + clip: true + Rectangle { + color: "lightGreen" + width: 50 + height: 50 + x: 275 + y: 75 + } + } + Rectangle { + color: "white" + width: 300 + height: 100 + Text { text: "this is not a layer" } + } + Rectangle { + color: "green" + width: 300 + height: 100 + layer.enabled: true + Text { text: "this is another layer" } + Rectangle { + border.width: 4 + border.color: "black" + anchors.centerIn: parent + width: 150 + height: 50 + layer.enabled: true + Text { + anchors.centerIn: parent + text: "layer in a layer" + } + } + Image { + source: "qrc:/face-smile.png" + anchors.bottom: parent.bottom + anchors.right: parent.right + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + } + } + } + } +} diff --git a/tests/manual/nodetypes/LotsOfRects.qml b/tests/manual/nodetypes/LotsOfRects.qml new file mode 100644 index 0000000000..46a05a2453 --- /dev/null +++ b/tests/manual/nodetypes/LotsOfRects.qml @@ -0,0 +1,250 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + Rectangle { + anchors.margins: 4 + anchors.fill: parent + + // Background + gradient: Gradient { + GradientStop { position: 0; color: "steelblue" } + GradientStop { position: 1; color: "black" } + } + + // Animated gradient stops. + // NB! Causes a full buffer rebuild on every animated change due to the geometry change! + Row { + spacing: 10 + Repeater { + model: 20 + Rectangle { + width: 20 + height: 20 + gradient: Gradient { + GradientStop { position: 0.0; color: "red" } + GradientStop { NumberAnimation on position { from: 0.01; to: 0.99; duration: 5000; loops: Animation.Infinite } color: "yellow" } + GradientStop { position: 1.0; color: "green" } + } + } + } + } + + // Rounded rects with border (smooth material) + Row { + spacing: 10 + Repeater { + model: 5 + Rectangle { + color: "blue" + width: 100 + height: 50 + y: 50 + radius: 16 + border.color: "red" + border.width: 4 + + SequentialAnimation on y { + loops: Animation.Infinite + NumberAnimation { + from: 50 + to: 150 + duration: 7000 + } + NumberAnimation { + from: 150 + to: 50 + duration: 3000 + } + } + } + } + } + + // Clip using scissor + Row { + spacing: 10 + Repeater { + model: 5 + Rectangle { + color: "green" + width: 100 + height: 100 + y: 150 + NumberAnimation on y { + from: 150 + to: 200 + duration: 2000 + loops: Animation.Infinite + } + clip: true + Rectangle { + color: "lightGreen" + width: 50 + height: 50 + x: 75 + y: 75 + } + } + } + } + + // Clip using scissor + Row { + spacing: 10 + Repeater { + model: 5 + Rectangle { + color: "green" + width: 100 + height: 100 + y: 300 + NumberAnimation on y { + from: 300 + to: 400 + duration: 2000 + loops: Animation.Infinite + } + clip: true + Rectangle { + color: "lightGreen" + width: 50 + height: 50 + x: 75 + y: 75 + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + } + } + } + } + + // Clip using stencil + Row { + spacing: 10 + Repeater { + model: 5 + Rectangle { + color: "green" + width: 100 + height: 100 + y: 450 + NumberAnimation on y { + from: 450 + to: 550 + duration: 2000 + loops: Animation.Infinite + } + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + clip: true + Rectangle { + color: "lightGreen" + width: 50 + height: 50 + x: 75 + y: 75 + } + } + } + } + + // The signature red square with another item with animated opacity blended on top + Rectangle { + width: 100 + height: 100 + anchors.centerIn: parent + color: "red" + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + + Rectangle { + color: "gray" + width: 50 + height: 50 + anchors.centerIn: parent + + SequentialAnimation on opacity { + loops: Animation.Infinite + NumberAnimation { + from: 1.0 + to: 0.0 + duration: 4000 + } + NumberAnimation { + from: 0.0 + to: 1.0 + duration: 4000 + easing.type: Easing.InOutQuad + } + } + } + } + + // Animated size and color. + // NB! Causes a full buffer rebuild on every animated change due to the geometry change! + Rectangle { + anchors.right: parent.right + anchors.bottom: parent.bottom + width: 10 + height: 100 + ColorAnimation on color { + from: "blue" + to: "purple" + duration: 5000 + loops: Animation.Infinite + } + NumberAnimation on width { + from: 10 + to: 300 + duration: 5000 + loops: Animation.Infinite + } + } + + // Semi-transparent rect on top. + Rectangle { + anchors.centerIn: parent + opacity: 0.2 + color: "black" + anchors.fill: parent + anchors.margins: 10 + } + } +} diff --git a/tests/manual/nodetypes/Rects.qml b/tests/manual/nodetypes/Rects.qml new file mode 100644 index 0000000000..0d3a8cd459 --- /dev/null +++ b/tests/manual/nodetypes/Rects.qml @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + Rectangle { + width: 100 + height: 100 + anchors.centerIn: parent + color: "red" + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + + Rectangle { + color: "gray" + width: 50 + height: 50 + anchors.centerIn: parent + + SequentialAnimation on opacity { + loops: Animation.Infinite + NumberAnimation { + from: 1.0 + to: 0.0 + duration: 4000 + } + NumberAnimation { + from: 0.0 + to: 1.0 + duration: 4000 + easing.type: Easing.InOutQuad + } + } + } + } + + Rectangle { + color: "green" + width: 100 + height: 200 + x: 0 + y: 0 + + NumberAnimation on x { + from: 0 + to: 300 + duration: 5000 + } + NumberAnimation on y { + from: 0 + to: 50 + duration: 2000 + } + + clip: true + Rectangle { + color: "lightGreen" + width: 50 + height: 50 + x: 75 + y: 175 + } + } + + Rectangle { + color: "blue" + width: 200 + height: 100 + x: 100 + y: 300 + radius: 16 + border.color: "red" + border.width: 4 + + SequentialAnimation on y { + loops: Animation.Infinite + NumberAnimation { + from: 300 + to: 500 + duration: 7000 + } + NumberAnimation { + from: 500 + to: 300 + duration: 3000 + } + } + } + + Rectangle { + anchors.right: parent.right + width: 100 + height: 100 + gradient: Gradient { + GradientStop { position: 0.0; color: "red" } + GradientStop { position: 0.33; color: "yellow" } + GradientStop { position: 1.0; color: "green" } + } + } +} diff --git a/tests/manual/nodetypes/Text.qml b/tests/manual/nodetypes/Text.qml new file mode 100644 index 0000000000..fb0c92cb10 --- /dev/null +++ b/tests/manual/nodetypes/Text.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + Text { + id: text1 + anchors.top: parent.top + text: "árvíztűrő tükörfúrógép\nÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP" + } + Text { + anchors.bottom: parent.bottom + text: "the quick brown fox jumps over the lazy dog\nTHE QUICK BROWN FOX JUMPS OVER THE LAZY DOG" + color: "red" + } + Text { + anchors.centerIn: parent + text: "rotate rotate rotate" + font.bold: true + font.pointSize: 20 + color: "green" + NumberAnimation on rotation { from: 0; to: 360; duration: 2000; loops: Animation.Infinite; } + } + + Row { + anchors.top: text1.bottom + anchors.margins: 10 + Text { font.pointSize: 24; text: "Normal" } + Text { font.pointSize: 24; text: "Raised"; style: Text.Raised; styleColor: "#AAAAAA" } + Text { font.pointSize: 24; text: "Outline"; style: Text.Outline; styleColor: "red" } + Text { font.pointSize: 24; text: "Sunken"; style: Text.Sunken; styleColor: "#AAAAAA" } + } +} diff --git a/tests/manual/nodetypes/face-smile.png b/tests/manual/nodetypes/face-smile.png Binary files differnew file mode 100644 index 0000000000..3d66d72578 --- /dev/null +++ b/tests/manual/nodetypes/face-smile.png diff --git a/tests/manual/nodetypes/main.qml b/tests/manual/nodetypes/main.qml new file mode 100644 index 0000000000..fe75e2d948 --- /dev/null +++ b/tests/manual/nodetypes/main.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + focus: true + + Loader { + anchors.fill: parent + id: loader + } + + Keys.onPressed: { + if (event.key === Qt.Key_S) + loader.source = ""; + + if (event.key === Qt.Key_R) + loader.source = "qrc:/Rects.qml"; + if (event.key === Qt.Key_4) + loader.source = "qrc:/LotsOfRects.qml"; + + if (event.key === Qt.Key_I) + loader.source = "qrc:/Images.qml"; + + if (event.key === Qt.Key_T) + loader.source = "qrc:/Text.qml"; + + if (event.key === Qt.Key_A) + loader.source = "qrc:/Animators.qml"; + + if (event.key === Qt.Key_L) + loader.source = "qrc:/Layers.qml"; + } +} diff --git a/tests/manual/nodetypes/nodetypes.cpp b/tests/manual/nodetypes/nodetypes.cpp new file mode 100644 index 0000000000..aaa641f300 --- /dev/null +++ b/tests/manual/nodetypes/nodetypes.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QThread> +#include <QQuickView> +#include <QQmlEngine> +#include <QQmlContext> + +class Helper : public QObject +{ + Q_OBJECT + +public: + Q_INVOKABLE void sleep(int ms) { + QThread::msleep(ms); + } +}; + +int main(int argc, char **argv) +{ + qputenv("QT_QUICK_BACKEND", "d3d12"); + + QGuiApplication app(argc, argv); + + qDebug("Available tests:"); + qDebug(" [R] - Rectangles"); + qDebug(" [4] - A lot of rectangles (perf)"); + qDebug(" [I] - Images"); + qDebug(" [T] - Text"); + qDebug(" [A] - Render thread Animator"); + qDebug(" [L] - Layers"); + qDebug("\nPress S to stop the currently running test\n"); + + Helper helper; + QQuickView view; + if (app.arguments().contains(QLatin1String("--multisample"))) { + qDebug("Requesting sample count 4"); + QSurfaceFormat fmt; + fmt.setSamples(4); + view.setFormat(fmt); + } + view.engine()->rootContext()->setContextProperty(QLatin1String("helper"), &helper); + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.resize(1024, 768); + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} + +#include "nodetypes.moc" diff --git a/tests/manual/nodetypes/nodetypes.pro b/tests/manual/nodetypes/nodetypes.pro new file mode 100644 index 0000000000..a1633dcf22 --- /dev/null +++ b/tests/manual/nodetypes/nodetypes.pro @@ -0,0 +1,7 @@ +QT += qml quick + +SOURCES += nodetypes.cpp + +RESOURCES += nodetypes.qrc + +OTHER_FILES += main.qml Rects.qml LotsOfRects.qml Images.qml Text.qml Animators.qml Layers.qml diff --git a/tests/manual/nodetypes/nodetypes.qrc b/tests/manual/nodetypes/nodetypes.qrc new file mode 100644 index 0000000000..b10fceef24 --- /dev/null +++ b/tests/manual/nodetypes/nodetypes.qrc @@ -0,0 +1,14 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>Rects.qml</file> + <file>LotsOfRects.qml</file> + <file>Images.qml</file> + <file>Text.qml</file> + <file>Animators.qml</file> + <file>Layers.qml</file> + <file>qt.png</file> + <file>face-smile.png</file> + <file>shadow.png</file> + </qresource> +</RCC> diff --git a/tests/manual/nodetypes/qt.png b/tests/manual/nodetypes/qt.png Binary files differnew file mode 100644 index 0000000000..f30eec0d4d --- /dev/null +++ b/tests/manual/nodetypes/qt.png diff --git a/tests/manual/nodetypes/shadow.png b/tests/manual/nodetypes/shadow.png Binary files differnew file mode 100644 index 0000000000..8270565e87 --- /dev/null +++ b/tests/manual/nodetypes/shadow.png diff --git a/tools/opengldummy/3rdparty/include/EGL/egl.h b/tools/opengldummy/3rdparty/include/EGL/egl.h new file mode 100644 index 0000000000..99ea342a47 --- /dev/null +++ b/tools/opengldummy/3rdparty/include/EGL/egl.h @@ -0,0 +1,329 @@ +/* -*- mode: c; tab-width: 8; -*- */ +/* vi: set sw=4 ts=8: */ +/* Reference version of egl.h for EGL 1.4. + * $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $ + */ + +/* +** Copyright (c) 2007-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#ifndef __egl_h_ +#define __egl_h_ + +/* All platform-dependent types and macro boilerplate (such as EGLAPI + * and EGLAPIENTRY) should go in eglplatform.h. + */ +#include <EGL/eglplatform.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* EGL Types */ +/* EGLint is defined in eglplatform.h */ +typedef unsigned int EGLBoolean; +typedef unsigned int EGLenum; +typedef void *EGLConfig; +typedef void *EGLContext; +typedef void *EGLDisplay; +typedef void *EGLSurface; +typedef void *EGLClientBuffer; + +/* EGL Versioning */ +#define EGL_VERSION_1_0 1 +#define EGL_VERSION_1_1 1 +#define EGL_VERSION_1_2 1 +#define EGL_VERSION_1_3 1 +#define EGL_VERSION_1_4 1 + +/* EGL Enumerants. Bitmasks and other exceptional cases aside, most + * enums are assigned unique values starting at 0x3000. + */ + +/* EGL aliases */ +#define EGL_FALSE 0 +#define EGL_TRUE 1 + +/* Out-of-band handle values */ +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#define EGL_NO_CONTEXT ((EGLContext)0) +#define EGL_NO_DISPLAY ((EGLDisplay)0) +#define EGL_NO_SURFACE ((EGLSurface)0) + +/* Out-of-band attribute value */ +#define EGL_DONT_CARE ((EGLint)-1) + +/* Errors / GetError return values */ +#define EGL_SUCCESS 0x3000 +#define EGL_NOT_INITIALIZED 0x3001 +#define EGL_BAD_ACCESS 0x3002 +#define EGL_BAD_ALLOC 0x3003 +#define EGL_BAD_ATTRIBUTE 0x3004 +#define EGL_BAD_CONFIG 0x3005 +#define EGL_BAD_CONTEXT 0x3006 +#define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DISPLAY 0x3008 +#define EGL_BAD_MATCH 0x3009 +#define EGL_BAD_NATIVE_PIXMAP 0x300A +#define EGL_BAD_NATIVE_WINDOW 0x300B +#define EGL_BAD_PARAMETER 0x300C +#define EGL_BAD_SURFACE 0x300D +#define EGL_CONTEXT_LOST 0x300E /* EGL 1.1 - IMG_power_management */ + +/* Reserved 0x300F-0x301F for additional errors */ + +/* Config attributes */ +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BLUE_SIZE 0x3022 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_RED_SIZE 0x3024 +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_NONE 0x3038 /* Attrib list terminator */ +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */ +#define EGL_CONFORMANT 0x3042 + +/* Reserved 0x3041-0x304F for additional config attributes */ + +/* Config attribute values */ +#define EGL_SLOW_CONFIG 0x3050 /* EGL_CONFIG_CAVEAT value */ +#define EGL_NON_CONFORMANT_CONFIG 0x3051 /* EGL_CONFIG_CAVEAT value */ +#define EGL_TRANSPARENT_RGB 0x3052 /* EGL_TRANSPARENT_TYPE value */ +#define EGL_RGB_BUFFER 0x308E /* EGL_COLOR_BUFFER_TYPE value */ +#define EGL_LUMINANCE_BUFFER 0x308F /* EGL_COLOR_BUFFER_TYPE value */ + +/* More config attribute values, for EGL_TEXTURE_FORMAT */ +#define EGL_NO_TEXTURE 0x305C +#define EGL_TEXTURE_RGB 0x305D +#define EGL_TEXTURE_RGBA 0x305E +#define EGL_TEXTURE_2D 0x305F + +/* Config attribute mask bits */ +#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */ + +#define EGL_OPENGL_ES_BIT 0x0001 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENVG_BIT 0x0002 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */ + +/* QueryString targets */ +#define EGL_VENDOR 0x3053 +#define EGL_VERSION 0x3054 +#define EGL_EXTENSIONS 0x3055 +#define EGL_CLIENT_APIS 0x308D + +/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */ +#define EGL_HEIGHT 0x3056 +#define EGL_WIDTH 0x3057 +#define EGL_LARGEST_PBUFFER 0x3058 +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_TARGET 0x3081 +#define EGL_MIPMAP_TEXTURE 0x3082 +#define EGL_MIPMAP_LEVEL 0x3083 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_VG_COLORSPACE 0x3087 +#define EGL_VG_ALPHA_FORMAT 0x3088 +#define EGL_HORIZONTAL_RESOLUTION 0x3090 +#define EGL_VERTICAL_RESOLUTION 0x3091 +#define EGL_PIXEL_ASPECT_RATIO 0x3092 +#define EGL_SWAP_BEHAVIOR 0x3093 +#define EGL_MULTISAMPLE_RESOLVE 0x3099 + +/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */ +#define EGL_BACK_BUFFER 0x3084 +#define EGL_SINGLE_BUFFER 0x3085 + +/* OpenVG color spaces */ +#define EGL_VG_COLORSPACE_sRGB 0x3089 /* EGL_VG_COLORSPACE value */ +#define EGL_VG_COLORSPACE_LINEAR 0x308A /* EGL_VG_COLORSPACE value */ + +/* OpenVG alpha formats */ +#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B /* EGL_ALPHA_FORMAT value */ +#define EGL_VG_ALPHA_FORMAT_PRE 0x308C /* EGL_ALPHA_FORMAT value */ + +/* Constant scale factor by which fractional display resolutions & + * aspect ratio are scaled when queried as integer values. + */ +#define EGL_DISPLAY_SCALING 10000 + +/* Unknown display resolution/aspect ratio */ +#define EGL_UNKNOWN ((EGLint)-1) + +/* Back buffer swap behaviors */ +#define EGL_BUFFER_PRESERVED 0x3094 /* EGL_SWAP_BEHAVIOR value */ +#define EGL_BUFFER_DESTROYED 0x3095 /* EGL_SWAP_BEHAVIOR value */ + +/* CreatePbufferFromClientBuffer buffer types */ +#define EGL_OPENVG_IMAGE 0x3096 + +/* QueryContext targets */ +#define EGL_CONTEXT_CLIENT_TYPE 0x3097 + +/* CreateContext attributes */ +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 + +/* Multisample resolution behaviors */ +#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A /* EGL_MULTISAMPLE_RESOLVE value */ +#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B /* EGL_MULTISAMPLE_RESOLVE value */ + +/* BindAPI/QueryAPI targets */ +#define EGL_OPENGL_ES_API 0x30A0 +#define EGL_OPENVG_API 0x30A1 +#define EGL_OPENGL_API 0x30A2 + +/* GetCurrentSurface targets */ +#define EGL_DRAW 0x3059 +#define EGL_READ 0x305A + +/* WaitNative engines */ +#define EGL_CORE_NATIVE_ENGINE 0x305B + +/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */ +#define EGL_COLORSPACE EGL_VG_COLORSPACE +#define EGL_ALPHA_FORMAT EGL_VG_ALPHA_FORMAT +#define EGL_COLORSPACE_sRGB EGL_VG_COLORSPACE_sRGB +#define EGL_COLORSPACE_LINEAR EGL_VG_COLORSPACE_LINEAR +#define EGL_ALPHA_FORMAT_NONPRE EGL_VG_ALPHA_FORMAT_NONPRE +#define EGL_ALPHA_FORMAT_PRE EGL_VG_ALPHA_FORMAT_PRE + +/* EGL extensions must request enum blocks from the Khronos + * API Registrar, who maintains the enumerant registry. Submit + * a bug in Khronos Bugzilla against task "Registry". + */ + + + +/* EGL Functions */ + +EGLAPI EGLint EGLAPIENTRY eglGetError(void); + +EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id); +EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor); +EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy); + +EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name); + +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, + EGLint config_size, EGLint *num_config); +EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, + EGLConfig *configs, EGLint config_size, + EGLint *num_config); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, + EGLint attribute, EGLint *value); + +EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, + EGLNativeWindowType win, + const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, + EGLNativePixmapType pixmap, + const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, + EGLint attribute, EGLint *value); + +EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api); +EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void); + +EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void); + +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void); + +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer( + EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, + EGLConfig config, const EGLint *attrib_list); + +EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, + EGLint attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); + + +EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval); + + +EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, + EGLContext share_context, + const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, + EGLSurface read, EGLContext ctx); + +EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void); +EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw); +EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, + EGLint attribute, EGLint *value); + +EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, + EGLNativePixmapType target); + +/* This is a generic function pointer type, whose name indicates it must + * be cast to the proper type *and calling convention* before use. + */ +typedef void (*__eglMustCastToProperFunctionPointerType)(void); + +/* Now, define eglGetProcAddress using the generic function ptr. type */ +EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY + eglGetProcAddress(const char *procname); + +#ifdef __cplusplus +} +#endif + +#endif /* __egl_h_ */ diff --git a/tools/opengldummy/3rdparty/include/EGL/eglext.h b/tools/opengldummy/3rdparty/include/EGL/eglext.h new file mode 100644 index 0000000000..a392b31d9d --- /dev/null +++ b/tools/opengldummy/3rdparty/include/EGL/eglext.h @@ -0,0 +1,628 @@ +#ifndef __eglext_h_ +#define __eglext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 23535 $ on $Date: 2013-10-16 10:29:40 -0700 (Wed, 16 Oct 2013) $ +*/ + +#include <EGL/eglplatform.h> + +#define EGL_EGLEXT_VERSION 20131016 + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: _nomatch_^ + * Default extensions included: egl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_KHR_cl_event +#define EGL_KHR_cl_event 1 +#define EGL_CL_EVENT_HANDLE_KHR 0x309C +#define EGL_SYNC_CL_EVENT_KHR 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF +#endif /* EGL_KHR_cl_event */ + +#ifndef EGL_KHR_client_get_all_proc_addresses +#define EGL_KHR_client_get_all_proc_addresses 1 +#endif /* EGL_KHR_client_get_all_proc_addresses */ + +#ifndef EGL_KHR_config_attribs +#define EGL_KHR_config_attribs 1 +#define EGL_CONFORMANT_KHR 0x3042 +#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 +#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 +#endif /* EGL_KHR_config_attribs */ + +#ifndef EGL_KHR_create_context +#define EGL_KHR_create_context 1 +#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB +#define EGL_CONTEXT_FLAGS_KHR 0x30FC +#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD +#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF +#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 +#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 +#endif /* EGL_KHR_create_context */ + +#ifndef EGL_KHR_fence_sync +#define EGL_KHR_fence_sync 1 +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE_KHR 0x30F9 +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_fence_sync */ + +#ifndef EGL_KHR_get_all_proc_addresses +#define EGL_KHR_get_all_proc_addresses 1 +#endif /* EGL_KHR_get_all_proc_addresses */ + +#ifndef EGL_KHR_gl_renderbuffer_image +#define EGL_KHR_gl_renderbuffer_image 1 +#define EGL_GL_RENDERBUFFER_KHR 0x30B9 +#endif /* EGL_KHR_gl_renderbuffer_image */ + +#ifndef EGL_KHR_gl_texture_2D_image +#define EGL_KHR_gl_texture_2D_image 1 +#define EGL_GL_TEXTURE_2D_KHR 0x30B1 +#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC +#endif /* EGL_KHR_gl_texture_2D_image */ + +#ifndef EGL_KHR_gl_texture_3D_image +#define EGL_KHR_gl_texture_3D_image 1 +#define EGL_GL_TEXTURE_3D_KHR 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD +#endif /* EGL_KHR_gl_texture_3D_image */ + +#ifndef EGL_KHR_gl_texture_cubemap_image +#define EGL_KHR_gl_texture_cubemap_image 1 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 +#endif /* EGL_KHR_gl_texture_cubemap_image */ + +#ifndef EGL_KHR_image +#define EGL_KHR_image 1 +typedef void *EGLImageKHR; +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 +#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_KHR_image */ + +#ifndef EGL_KHR_image_base +#define EGL_KHR_image_base 1 +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 +#endif /* EGL_KHR_image_base */ + +#ifndef EGL_KHR_image_pixmap +#define EGL_KHR_image_pixmap 1 +#endif /* EGL_KHR_image_pixmap */ + +#ifndef EGL_KHR_lock_surface +#define EGL_KHR_lock_surface 1 +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 +#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 +#define EGL_MATCH_FORMAT_KHR 0x3043 +#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 +#define EGL_FORMAT_RGB_565_KHR 0x30C1 +#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 +#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#define EGL_BITMAP_ORIGIN_KHR 0x30C8 +#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 +#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA +#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB +#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC +#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD +#define EGL_LOWER_LEFT_KHR 0x30CE +#define EGL_UPPER_LEFT_KHR 0x30CF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface); +#endif +#endif /* EGL_KHR_lock_surface */ + +#ifndef EGL_KHR_lock_surface2 +#define EGL_KHR_lock_surface2 1 +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 +#endif /* EGL_KHR_lock_surface2 */ + +#ifndef EGL_KHR_reusable_sync +#define EGL_KHR_reusable_sync 1 +typedef void *EGLSyncKHR; +typedef khronos_utime_nanoseconds_t EGLTimeKHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_STATUS_KHR 0x30F1 +#define EGL_SIGNALED_KHR 0x30F2 +#define EGL_UNSIGNALED_KHR 0x30F3 +#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 +#define EGL_CONDITION_SATISFIED_KHR 0x30F6 +#define EGL_SYNC_TYPE_KHR 0x30F7 +#define EGL_SYNC_REUSABLE_KHR 0x30FA +#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 +#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull +#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_reusable_sync */ + +#ifndef EGL_KHR_stream +#define EGL_KHR_stream 1 +typedef void *EGLStreamKHR; +typedef khronos_uint64_t EGLuint64KHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0) +#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 +#define EGL_PRODUCER_FRAME_KHR 0x3212 +#define EGL_CONSUMER_FRAME_KHR 0x3213 +#define EGL_STREAM_STATE_KHR 0x3214 +#define EGL_STREAM_STATE_CREATED_KHR 0x3215 +#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 +#define EGL_STREAM_STATE_EMPTY_KHR 0x3217 +#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218 +#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219 +#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A +#define EGL_BAD_STREAM_KHR 0x321B +#define EGL_BAD_STATE_KHR 0x321C +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream */ + +#ifndef EGL_KHR_stream_consumer_gltexture +#define EGL_KHR_stream_consumer_gltexture 1 +#ifdef EGL_KHR_stream +#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_consumer_gltexture */ + +#ifndef EGL_KHR_stream_cross_process_fd +#define EGL_KHR_stream_cross_process_fd 1 +typedef int EGLNativeFileDescriptorKHR; +#ifdef EGL_KHR_stream +#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1)) +typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_cross_process_fd */ + +#ifndef EGL_KHR_stream_fifo +#define EGL_KHR_stream_fifo 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC +#define EGL_STREAM_TIME_NOW_KHR 0x31FD +#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE +#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_fifo */ + +#ifndef EGL_KHR_stream_producer_aldatalocator +#define EGL_KHR_stream_producer_aldatalocator 1 +#ifdef EGL_KHR_stream +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_aldatalocator */ + +#ifndef EGL_KHR_stream_producer_eglsurface +#define EGL_KHR_stream_producer_eglsurface 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_BIT_KHR 0x0800 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_eglsurface */ + +#ifndef EGL_KHR_surfaceless_context +#define EGL_KHR_surfaceless_context 1 +#endif /* EGL_KHR_surfaceless_context */ + +#ifndef EGL_KHR_vg_parent_image +#define EGL_KHR_vg_parent_image 1 +#define EGL_VG_PARENT_IMAGE_KHR 0x30BA +#endif /* EGL_KHR_vg_parent_image */ + +#ifndef EGL_KHR_wait_sync +#define EGL_KHR_wait_sync 1 +typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#endif +#endif /* EGL_KHR_wait_sync */ + +#ifndef EGL_ANDROID_blob_cache +#define EGL_ANDROID_blob_cache 1 +typedef khronos_ssize_t EGLsizeiANDROID; +typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); +typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); +typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#endif +#endif /* EGL_ANDROID_blob_cache */ + +#ifndef EGL_ANDROID_framebuffer_target +#define EGL_ANDROID_framebuffer_target 1 +#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 +#endif /* EGL_ANDROID_framebuffer_target */ + +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 +#endif /* EGL_ANDROID_image_native_buffer */ + +#ifndef EGL_ANDROID_native_fence_sync +#define EGL_ANDROID_native_fence_sync 1 +#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144 +#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145 +#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146 +#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1 +typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync); +#endif +#endif /* EGL_ANDROID_native_fence_sync */ + +#ifndef EGL_ANDROID_recordable +#define EGL_ANDROID_recordable 1 +#define EGL_RECORDABLE_ANDROID 0x3142 +#endif /* EGL_ANDROID_recordable */ + +#ifndef EGL_ANGLE_d3d_share_handle_client_buffer +#define EGL_ANGLE_d3d_share_handle_client_buffer 1 +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */ + +#ifndef EGL_ANGLE_query_surface_pointer +#define EGL_ANGLE_query_surface_pointer 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif +#endif /* EGL_ANGLE_query_surface_pointer */ + +#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle +#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 +#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ + +#ifndef EGL_ARM_pixmap_multisample_discard +#define EGL_ARM_pixmap_multisample_discard 1 +#define EGL_DISCARD_SAMPLES_ARM 0x3286 +#endif /* EGL_ARM_pixmap_multisample_discard */ + +#ifndef EGL_EXT_buffer_age +#define EGL_EXT_buffer_age 1 +#define EGL_BUFFER_AGE_EXT 0x313D +#endif /* EGL_EXT_buffer_age */ + +#ifndef EGL_EXT_client_extensions +#define EGL_EXT_client_extensions 1 +#endif /* EGL_EXT_client_extensions */ + +#ifndef EGL_EXT_create_context_robustness +#define EGL_EXT_create_context_robustness 1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 +#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF +#endif /* EGL_EXT_create_context_robustness */ + +#ifndef EGL_EXT_image_dma_buf_import +#define EGL_EXT_image_dma_buf_import 1 +#define EGL_LINUX_DMA_BUF_EXT 0x3270 +#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 +#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 +#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 +#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 +#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 +#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 +#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 +#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 +#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 +#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A +#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B +#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C +#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D +#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E +#define EGL_ITU_REC601_EXT 0x327F +#define EGL_ITU_REC709_EXT 0x3280 +#define EGL_ITU_REC2020_EXT 0x3281 +#define EGL_YUV_FULL_RANGE_EXT 0x3282 +#define EGL_YUV_NARROW_RANGE_EXT 0x3283 +#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284 +#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 +#endif /* EGL_EXT_image_dma_buf_import */ + +#ifndef EGL_EXT_multiview_window +#define EGL_EXT_multiview_window 1 +#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 +#endif /* EGL_EXT_multiview_window */ + +#ifndef EGL_EXT_platform_base +#define EGL_EXT_platform_base 1 +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#endif +#endif /* EGL_EXT_platform_base */ + +#ifndef EGL_EXT_platform_wayland +#define EGL_EXT_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_EXT 0x31D8 +#endif /* EGL_EXT_platform_wayland */ + +#ifndef EGL_EXT_platform_x11 +#define EGL_EXT_platform_x11 1 +#define EGL_PLATFORM_X11_EXT 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 +#endif /* EGL_EXT_platform_x11 */ + +#ifndef EGL_EXT_swap_buffers_with_damage +#define EGL_EXT_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_EXT_swap_buffers_with_damage */ + +#ifndef EGL_HI_clientpixmap +#define EGL_HI_clientpixmap 1 +struct EGLClientPixmapHI { + void *pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; +}; +#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#endif +#endif /* EGL_HI_clientpixmap */ + +#ifndef EGL_HI_colorformats +#define EGL_HI_colorformats 1 +#define EGL_COLOR_FORMAT_HI 0x8F70 +#define EGL_COLOR_RGB_HI 0x8F71 +#define EGL_COLOR_RGBA_HI 0x8F72 +#define EGL_COLOR_ARGB_HI 0x8F73 +#endif /* EGL_HI_colorformats */ + +#ifndef EGL_IMG_context_priority +#define EGL_IMG_context_priority 1 +#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 +#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 +#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 +#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 +#endif /* EGL_IMG_context_priority */ + +#ifndef EGL_MESA_drm_image +#define EGL_MESA_drm_image 1 +#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 +#define EGL_DRM_BUFFER_USE_MESA 0x31D1 +#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 +#define EGL_DRM_BUFFER_MESA 0x31D3 +#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 +#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 +#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif +#endif /* EGL_MESA_drm_image */ + +#ifndef EGL_MESA_platform_gbm +#define EGL_MESA_platform_gbm 1 +#define EGL_PLATFORM_GBM_MESA 0x31D7 +#endif /* EGL_MESA_platform_gbm */ + +#ifndef EGL_NV_3dvision_surface +#define EGL_NV_3dvision_surface 1 +#define EGL_AUTO_STEREO_NV 0x3136 +#endif /* EGL_NV_3dvision_surface */ + +#ifndef EGL_NV_coverage_sample +#define EGL_NV_coverage_sample 1 +#define EGL_COVERAGE_BUFFERS_NV 0x30E0 +#define EGL_COVERAGE_SAMPLES_NV 0x30E1 +#endif /* EGL_NV_coverage_sample */ + +#ifndef EGL_NV_coverage_sample_resolve +#define EGL_NV_coverage_sample_resolve 1 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 +#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 +#endif /* EGL_NV_coverage_sample_resolve */ + +#ifndef EGL_NV_depth_nonlinear +#define EGL_NV_depth_nonlinear 1 +#define EGL_DEPTH_ENCODING_NV 0x30E2 +#define EGL_DEPTH_ENCODING_NONE_NV 0 +#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 +#endif /* EGL_NV_depth_nonlinear */ + +#ifndef EGL_NV_native_query +#define EGL_NV_native_query 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#endif +#endif /* EGL_NV_native_query */ + +#ifndef EGL_NV_post_convert_rounding +#define EGL_NV_post_convert_rounding 1 +#endif /* EGL_NV_post_convert_rounding */ + +#ifndef EGL_NV_post_sub_buffer +#define EGL_NV_post_sub_buffer 1 +#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif +#endif /* EGL_NV_post_sub_buffer */ + +#ifndef EGL_NV_stream_sync +#define EGL_NV_stream_sync 1 +#define EGL_SYNC_NEW_FRAME_NV 0x321F +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#endif +#endif /* EGL_NV_stream_sync */ + +#ifndef EGL_NV_sync +#define EGL_NV_sync 1 +typedef void *EGLSyncNV; +typedef khronos_utime_nanoseconds_t EGLTimeNV; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6 +#define EGL_SYNC_STATUS_NV 0x30E7 +#define EGL_SIGNALED_NV 0x30E8 +#define EGL_UNSIGNALED_NV 0x30E9 +#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001 +#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull +#define EGL_ALREADY_SIGNALED_NV 0x30EA +#define EGL_TIMEOUT_EXPIRED_NV 0x30EB +#define EGL_CONDITION_SATISFIED_NV 0x30EC +#define EGL_SYNC_TYPE_NV 0x30ED +#define EGL_SYNC_CONDITION_NV 0x30EE +#define EGL_SYNC_FENCE_NV 0x30EF +#define EGL_NO_SYNC_NV ((EGLSyncNV)0) +typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync); +EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_sync */ + +#ifndef EGL_NV_system_time +#define EGL_NV_system_time 1 +typedef khronos_utime_nanoseconds_t EGLuint64NV; +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void); +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_system_time */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/opengldummy/3rdparty/include/EGL/eglplatform.h b/tools/opengldummy/3rdparty/include/EGL/eglplatform.h new file mode 100644 index 0000000000..bcbda98188 --- /dev/null +++ b/tools/opengldummy/3rdparty/include/EGL/eglplatform.h @@ -0,0 +1,143 @@ +#ifndef __eglplatform_h_ +#define __eglplatform_h_ + +/* +** Copyright (c) 2007-2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Platform-specific types and definitions for egl.h + * $Revision: 23432 $ on $Date: 2013-10-09 00:57:24 -0700 (Wed, 09 Oct 2013) $ + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "EGL" component "Registry". + */ + +#include <KHR/khrplatform.h> + +/* Macros used in EGL function prototype declarations. + * + * EGL functions should be prototyped as: + * + * EGLAPI return-type EGLAPIENTRY eglFunction(arguments); + * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments); + * + * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h + */ + +#ifndef EGLAPI +#define EGLAPI KHRONOS_APICALL +#endif + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY KHRONOS_APIENTRY +#endif +#define EGLAPIENTRYP EGLAPIENTRY* + +/* The types NativeDisplayType, NativeWindowType, and NativePixmapType + * are aliases of window-system-dependent types, such as X Display * or + * Windows Device Context. They must be defined in platform-specific + * code below. The EGL-prefixed versions of Native*Type are the same + * types, renamed in EGL 1.3 so all types in the API start with "EGL". + * + * Khronos STRONGLY RECOMMENDS that you use the default definitions + * provided below, since these changes affect both binary and source + * portability of applications using EGL running on different EGL + * implementations. + */ + +#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ + +#if 1 +/* QtGlesStream */ +typedef unsigned int EGLNativeDisplayType; +typedef unsigned int EGLNativeWindowType; +typedef unsigned int EGLNativePixmapType; +#else +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include <windows.h> + +typedef HDC EGLNativeDisplayType; +typedef HBITMAP EGLNativePixmapType; +typedef HWND EGLNativeWindowType; +#endif + +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ + +typedef int EGLNativeDisplayType; +typedef void *EGLNativeWindowType; +typedef void *EGLNativePixmapType; + +#elif defined(__ANDROID__) || defined(ANDROID) + +#include <android/native_window.h> + +struct egl_native_pixmap_t; + +typedef struct ANativeWindow* EGLNativeWindowType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef void* EGLNativeDisplayType; + +#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +#if 1 + +/* QtGlesStream */ +typedef unsigned int EGLNativeDisplayType; +typedef unsigned int EGLNativeWindowType; +typedef unsigned int EGLNativePixmapType; + +#else + +/* X11 (tentative) */ +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +typedef Display *EGLNativeDisplayType; +typedef Pixmap EGLNativePixmapType; +typedef Window EGLNativeWindowType; + +#endif + +#else +#error "Platform not recognized" +#endif + +/* EGL 1.2 types, renamed for consistency in EGL 1.3 */ +typedef EGLNativeDisplayType NativeDisplayType; +typedef EGLNativePixmapType NativePixmapType; +typedef EGLNativeWindowType NativeWindowType; + + +/* Define EGLint. This must be a signed integral type large enough to contain + * all legal attribute names and values passed into and out of EGL, whether + * their type is boolean, bitmask, enumerant (symbolic constant), integer, + * handle, or other. While in general a 32-bit integer will suffice, if + * handles are 64 bit types, then EGLint should be defined as a signed 64-bit + * integer type. + */ +typedef khronos_int32_t EGLint; + +#endif /* __eglplatform_h */ diff --git a/tools/opengldummy/3rdparty/include/GLES2/gl2.h b/tools/opengldummy/3rdparty/include/GLES2/gl2.h new file mode 100644 index 0000000000..f6bed7d1b3 --- /dev/null +++ b/tools/opengldummy/3rdparty/include/GLES2/gl2.h @@ -0,0 +1,523 @@ +#ifndef __gl2_h_ +#define __gl2_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision$ on $Date$ +*/ + +#include <GLES2/gl2platform.h> + +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9] + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_ES_VERSION_2_0 +#define GL_ES_VERSION_2_0 1 +#include <KHR/khrplatform.h> +typedef khronos_int8_t GLbyte; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef short GLshort; +typedef unsigned short GLushort; +typedef void GLvoid; +typedef struct __GLsync *GLsync; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef unsigned int GLenum; +typedef unsigned int GLuint; +typedef char GLchar; +typedef khronos_float_t GLfloat; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +typedef unsigned int GLbitfield; +typedef int GLint; +typedef unsigned char GLboolean; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_NONE 0 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif /* GL_ES_VERSION_2_0 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/opengldummy/3rdparty/include/GLES2/gl2ext.h b/tools/opengldummy/3rdparty/include/GLES2/gl2ext.h new file mode 100644 index 0000000000..36801bee5c --- /dev/null +++ b/tools/opengldummy/3rdparty/include/GLES2/gl2ext.h @@ -0,0 +1,1558 @@ +#ifndef __gl2ext_h_ +#define __gl2ext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 23581 $ on $Date: 2013-10-18 03:28:51 -0700 (Fri, 18 Oct 2013) $ +*/ + +#ifndef GL_APIENTRYP +#define GL_APIENTRYP GL_APIENTRY* +#endif + +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9] + * Versions emitted: _nomatch_^ + * Default extensions included: gles2 + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +typedef void (GL_APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_SAMPLER 0x82E6 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_BUFFER_KHR 0x82E0 +#define GL_SHADER_KHR 0x82E1 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_VERTEX_ARRAY_KHR 0x8074 +#define GL_QUERY_KHR 0x82E3 +#define GL_SAMPLER_KHR 0x82E6 +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam); +typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam); +GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void); +GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, void **params); +#endif +#endif /* GL_KHR_debug */ + +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif /* GL_KHR_texture_compression_astc_hdr */ + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif /* GL_KHR_texture_compression_astc_ldr */ + +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +typedef void *GLeglImageOES; +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +#endif /* GL_OES_EGL_image */ + +#ifndef GL_OES_EGL_image_external +#define GL_OES_EGL_image_external 1 +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#endif /* GL_OES_EGL_image_external */ + +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_OES_compressed_ETC1_RGB8_texture 1 +#define GL_ETC1_RGB8_OES 0x8D64 +#endif /* GL_OES_compressed_ETC1_RGB8_texture */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif /* GL_OES_compressed_paletted_texture */ + +#ifndef GL_OES_depth24 +#define GL_OES_depth24 1 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#endif /* GL_OES_depth24 */ + +#ifndef GL_OES_depth32 +#define GL_OES_depth32 1 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#endif /* GL_OES_depth32 */ + +#ifndef GL_OES_depth_texture +#define GL_OES_depth_texture 1 +#endif /* GL_OES_depth_texture */ + +#ifndef GL_OES_element_index_uint +#define GL_OES_element_index_uint 1 +#endif /* GL_OES_element_index_uint */ + +#ifndef GL_OES_fbo_render_mipmap +#define GL_OES_fbo_render_mipmap 1 +#endif /* GL_OES_fbo_render_mipmap */ + +#ifndef GL_OES_fragment_precision_high +#define GL_OES_fragment_precision_high 1 +#endif /* GL_OES_fragment_precision_high */ + +#ifndef GL_OES_get_program_binary +#define GL_OES_get_program_binary 1 +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const void *binary, GLint length); +#endif +#endif /* GL_OES_get_program_binary */ + +#ifndef GL_OES_mapbuffer +#define GL_OES_mapbuffer 1 +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +typedef void *(GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void *GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); +GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_OES_mapbuffer */ + +#ifndef GL_OES_packed_depth_stencil +#define GL_OES_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif /* GL_OES_packed_depth_stencil */ + +#ifndef GL_OES_required_internalformat +#define GL_OES_required_internalformat 1 +#define GL_ALPHA8_OES 0x803C +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_RGBA4_OES 0x8056 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB565_OES 0x8D62 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB10_A2_EXT 0x8059 +#endif /* GL_OES_required_internalformat */ + +#ifndef GL_OES_rgb8_rgba8 +#define GL_OES_rgb8_rgba8 1 +#endif /* GL_OES_rgb8_rgba8 */ + +#ifndef GL_OES_standard_derivatives +#define GL_OES_standard_derivatives 1 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#endif /* GL_OES_standard_derivatives */ + +#ifndef GL_OES_stencil1 +#define GL_OES_stencil1 1 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#endif /* GL_OES_stencil1 */ + +#ifndef GL_OES_stencil4 +#define GL_OES_stencil4 1 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#endif /* GL_OES_stencil4 */ + +#ifndef GL_OES_surfaceless_context +#define GL_OES_surfaceless_context 1 +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#endif /* GL_OES_surfaceless_context */ + +#ifndef GL_OES_texture_3D +#define GL_OES_texture_3D 1 +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif +#endif /* GL_OES_texture_3D */ + +#ifndef GL_OES_texture_compression_astc +#define GL_OES_texture_compression_astc 1 +#endif /* GL_OES_texture_compression_astc */ + +#ifndef GL_OES_texture_float +#define GL_OES_texture_float 1 +#endif /* GL_OES_texture_float */ + +#ifndef GL_OES_texture_float_linear +#define GL_OES_texture_float_linear 1 +#endif /* GL_OES_texture_float_linear */ + +#ifndef GL_OES_texture_half_float +#define GL_OES_texture_half_float 1 +#define GL_HALF_FLOAT_OES 0x8D61 +#endif /* GL_OES_texture_half_float */ + +#ifndef GL_OES_texture_half_float_linear +#define GL_OES_texture_half_float_linear 1 +#endif /* GL_OES_texture_half_float_linear */ + +#ifndef GL_OES_texture_npot +#define GL_OES_texture_npot 1 +#endif /* GL_OES_texture_npot */ + +#ifndef GL_OES_vertex_array_object +#define GL_OES_vertex_array_object 1 +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); +#endif +#endif /* GL_OES_vertex_array_object */ + +#ifndef GL_OES_vertex_half_float +#define GL_OES_vertex_half_float 1 +#endif /* GL_OES_vertex_half_float */ + +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_OES_vertex_type_10_10_10_2 1 +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#endif /* GL_OES_vertex_type_10_10_10_2 */ + +#ifndef GL_AMD_compressed_3DC_texture +#define GL_AMD_compressed_3DC_texture 1 +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA +#endif /* GL_AMD_compressed_3DC_texture */ + +#ifndef GL_AMD_compressed_ATC_texture +#define GL_AMD_compressed_ATC_texture 1 +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#endif /* GL_AMD_compressed_ATC_texture */ + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); +GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +#endif /* GL_AMD_performance_monitor */ + +#ifndef GL_AMD_program_binary_Z400 +#define GL_AMD_program_binary_Z400 1 +#define GL_Z400_BINARY_AMD 0x8740 +#endif /* GL_AMD_program_binary_Z400 */ + +#ifndef GL_ANGLE_depth_texture +#define GL_ANGLE_depth_texture 1 +#endif /* GL_ANGLE_depth_texture */ + +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_ANGLE_framebuffer_blit */ + +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_ANGLE_framebuffer_multisample */ + +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); +#endif +#endif /* GL_ANGLE_instanced_arrays */ + +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif /* GL_ANGLE_pack_reverse_row_order */ + +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#endif /* GL_ANGLE_program_binary */ + +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#endif /* GL_ANGLE_texture_compression_dxt3 */ + +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#endif /* GL_ANGLE_texture_compression_dxt5 */ + +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#endif /* GL_ANGLE_texture_usage */ + +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif +#endif /* GL_ANGLE_translated_shader_source */ + +#ifndef GL_APPLE_copy_texture_levels +#define GL_APPLE_copy_texture_levels 1 +typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif +#endif /* GL_APPLE_copy_texture_levels */ + +#ifndef GL_APPLE_framebuffer_multisample +#define GL_APPLE_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); +#endif +#endif /* GL_APPLE_framebuffer_multisample */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_RAW_422_APPLE 0x8A51 +#endif /* GL_APPLE_rgb_422 */ + +#ifndef GL_APPLE_sync +#define GL_APPLE_sync 1 +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif +#endif /* GL_APPLE_sync */ + +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_APPLE_texture_format_BGRA8888 1 +#define GL_BGRA_EXT 0x80E1 +#define GL_BGRA8_EXT 0x93A1 +#endif /* GL_APPLE_texture_format_BGRA8888 */ + +#ifndef GL_APPLE_texture_max_level +#define GL_APPLE_texture_max_level 1 +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#endif /* GL_APPLE_texture_max_level */ + +#ifndef GL_ARM_mali_program_binary +#define GL_ARM_mali_program_binary 1 +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#endif /* GL_ARM_mali_program_binary */ + +#ifndef GL_ARM_mali_shader_binary +#define GL_ARM_mali_shader_binary 1 +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#endif /* GL_ARM_mali_shader_binary */ + +#ifndef GL_ARM_rgba8 +#define GL_ARM_rgba8 1 +#endif /* GL_ARM_rgba8 */ + +#ifndef GL_DMP_shader_binary +#define GL_DMP_shader_binary 1 +#define GL_SHADER_BINARY_DMP 0x9250 +#endif /* GL_DMP_shader_binary */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#endif /* GL_EXT_blend_minmax */ + +#ifndef GL_EXT_color_buffer_half_float +#define GL_EXT_color_buffer_half_float 1 +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_RG16F_EXT 0x822F +#define GL_R16F_EXT 0x822D +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#endif /* GL_EXT_color_buffer_half_float */ + +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +#endif /* GL_EXT_debug_label */ + +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); +#endif +#endif /* GL_EXT_debug_marker */ + +#ifndef GL_EXT_discard_framebuffer +#define GL_EXT_discard_framebuffer 1 +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 +typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif +#endif /* GL_EXT_discard_framebuffer */ + +#ifndef GL_EXT_disjoint_timer_query +#define GL_EXT_disjoint_timer_query 1 +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_GPU_DISJOINT_EXT 0x8FBB +typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); +GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +#endif +#endif /* GL_EXT_disjoint_timer_query */ + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_EXT_draw_buffers */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_EXT_draw_instanced */ + +#ifndef GL_EXT_instanced_arrays +#define GL_EXT_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT (GLuint index, GLuint divisor); +#endif +#endif /* GL_EXT_instanced_arrays */ + +#ifndef GL_EXT_map_buffer_range +#define GL_EXT_map_buffer_range 1 +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void *GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length); +#endif +#endif /* GL_EXT_map_buffer_range */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#endif +#endif /* GL_EXT_multi_draw_arrays */ + +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +#endif /* GL_EXT_multisampled_render_to_texture */ + +#ifndef GL_EXT_multiview_draw_buffers +#define GL_EXT_multiview_draw_buffers 1 +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index); +GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices); +GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data); +#endif +#endif /* GL_EXT_multiview_draw_buffers */ + +#ifndef GL_EXT_occlusion_query_boolean +#define GL_EXT_occlusion_query_boolean 1 +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#endif /* GL_EXT_occlusion_query_boolean */ + +#ifndef GL_EXT_pvrtc_sRGB +#define GL_EXT_pvrtc_sRGB 1 +#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 +#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 +#endif /* GL_EXT_pvrtc_sRGB */ + +#ifndef GL_EXT_read_format_bgra +#define GL_EXT_read_format_bgra 1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#endif /* GL_EXT_read_format_bgra */ + +#ifndef GL_EXT_robustness +#define GL_EXT_robustness 1 +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); +GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif +#endif /* GL_EXT_robustness */ + +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#endif /* GL_EXT_sRGB */ + +#ifndef GL_EXT_sRGB_write_control +#define GL_EXT_sRGB_write_control 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#endif /* GL_EXT_sRGB_write_control */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); +GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_EXT_separate_shader_objects */ + +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif /* GL_EXT_shader_framebuffer_fetch */ + +#ifndef GL_EXT_shader_integer_mix +#define GL_EXT_shader_integer_mix 1 +#endif /* GL_EXT_shader_integer_mix */ + +#ifndef GL_EXT_shader_texture_lod +#define GL_EXT_shader_texture_lod 1 +#endif /* GL_EXT_shader_texture_lod */ + +#ifndef GL_EXT_shadow_samplers +#define GL_EXT_shadow_samplers 1 +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#endif /* GL_EXT_shadow_samplers */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif /* GL_EXT_texture_compression_dxt1 */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_EXT_texture_format_BGRA8888 1 +#endif /* GL_EXT_texture_format_BGRA8888 */ + +#ifndef GL_EXT_texture_rg +#define GL_EXT_texture_rg 1 +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#endif /* GL_EXT_texture_rg */ + +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif /* GL_EXT_texture_sRGB_decode */ + +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_R32F_EXT 0x822E +#define GL_RG32F_EXT 0x8230 +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* GL_EXT_texture_storage */ + +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_EXT_texture_type_2_10_10_10_REV 1 +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif /* GL_EXT_texture_type_2_10_10_10_REV */ + +#ifndef GL_EXT_unpack_subimage +#define GL_EXT_unpack_subimage 1 +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#endif /* GL_EXT_unpack_subimage */ + +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_FJ_shader_binary_GCCSO 1 +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#endif /* GL_FJ_shader_binary_GCCSO */ + +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +#endif /* GL_IMG_multisampled_render_to_texture */ + +#ifndef GL_IMG_program_binary +#define GL_IMG_program_binary 1 +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#endif /* GL_IMG_program_binary */ + +#ifndef GL_IMG_read_format +#define GL_IMG_read_format 1 +#define GL_BGRA_IMG 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#endif /* GL_IMG_read_format */ + +#ifndef GL_IMG_shader_binary +#define GL_IMG_shader_binary 1 +#define GL_SGX_BINARY_IMG 0x8C0A +#endif /* GL_IMG_shader_binary */ + +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_IMG_texture_compression_pvrtc 1 +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif /* GL_IMG_texture_compression_pvrtc */ + +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_IMG_texture_compression_pvrtc2 1 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#endif /* GL_IMG_texture_compression_pvrtc2 */ + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLUE_NV 0x1905 +#define GL_GREEN_NV 0x1904 +#define GL_RED_NV 0x1903 +#define GL_XOR_NV 0x1506 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +typedef void (GL_APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLBLENDBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlendParameteriNV (GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glBlendBarrierNV (void); +#endif +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_NV_blend_equation_advanced_coherent +#define GL_NV_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#endif /* GL_NV_blend_equation_advanced_coherent */ + +#ifndef GL_NV_copy_buffer +#define GL_NV_copy_buffer 1 +#define GL_COPY_READ_BUFFER_NV 0x8F36 +#define GL_COPY_WRITE_BUFFER_NV 0x8F37 +typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATANVPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyBufferSubDataNV (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#endif +#endif /* GL_NV_copy_buffer */ + +#ifndef GL_NV_coverage_sample +#define GL_NV_coverage_sample 1 +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); +typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); +GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); +#endif +#endif /* GL_NV_coverage_sample */ + +#ifndef GL_NV_depth_nonlinear +#define GL_NV_depth_nonlinear 1 +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#endif /* GL_NV_depth_nonlinear */ + +#ifndef GL_NV_draw_buffers +#define GL_NV_draw_buffers 1 +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_NV_draw_buffers */ + +#ifndef GL_NV_draw_instanced +#define GL_NV_draw_instanced 1 +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_NV_draw_instanced */ + +#ifndef GL_NV_explicit_attrib_location +#define GL_NV_explicit_attrib_location 1 +#endif /* GL_NV_explicit_attrib_location */ + +#ifndef GL_NV_fbo_color_attachments +#define GL_NV_fbo_color_attachments 1 +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +#endif /* GL_NV_fbo_color_attachments */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +#endif /* GL_NV_fence */ + +#ifndef GL_NV_framebuffer_blit +#define GL_NV_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_NV_framebuffer_blit */ + +#ifndef GL_NV_framebuffer_multisample +#define GL_NV_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_MAX_SAMPLES_NV 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_NV_framebuffer_multisample */ + +#ifndef GL_NV_generate_mipmap_sRGB +#define GL_NV_generate_mipmap_sRGB 1 +#endif /* GL_NV_generate_mipmap_sRGB */ + +#ifndef GL_NV_instanced_arrays +#define GL_NV_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor); +#endif +#endif /* GL_NV_instanced_arrays */ + +#ifndef GL_NV_non_square_matrices +#define GL_NV_non_square_matrices 1 +#define GL_FLOAT_MAT2x3_NV 0x8B65 +#define GL_FLOAT_MAT2x4_NV 0x8B66 +#define GL_FLOAT_MAT3x2_NV 0x8B67 +#define GL_FLOAT_MAT3x4_NV 0x8B68 +#define GL_FLOAT_MAT4x2_NV 0x8B69 +#define GL_FLOAT_MAT4x3_NV 0x8B6A +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_NV_non_square_matrices */ + +#ifndef GL_NV_read_buffer +#define GL_NV_read_buffer 1 +#define GL_READ_BUFFER_NV 0x0C02 +typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); +#endif +#endif /* GL_NV_read_buffer */ + +#ifndef GL_NV_read_buffer_front +#define GL_NV_read_buffer_front 1 +#endif /* GL_NV_read_buffer_front */ + +#ifndef GL_NV_read_depth +#define GL_NV_read_depth 1 +#endif /* GL_NV_read_depth */ + +#ifndef GL_NV_read_depth_stencil +#define GL_NV_read_depth_stencil 1 +#endif /* GL_NV_read_depth_stencil */ + +#ifndef GL_NV_read_stencil +#define GL_NV_read_stencil 1 +#endif /* GL_NV_read_stencil */ + +#ifndef GL_NV_sRGB_formats +#define GL_NV_sRGB_formats 1 +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SRGB8_NV 0x8C41 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_ETC1_SRGB8_NV 0x88EE +#endif /* GL_NV_sRGB_formats */ + +#ifndef GL_NV_shadow_samplers_array +#define GL_NV_shadow_samplers_array 1 +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#endif /* GL_NV_shadow_samplers_array */ + +#ifndef GL_NV_shadow_samplers_cube +#define GL_NV_shadow_samplers_cube 1 +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#endif /* GL_NV_shadow_samplers_cube */ + +#ifndef GL_NV_texture_border_clamp +#define GL_NV_texture_border_clamp 1 +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_CLAMP_TO_BORDER_NV 0x812D +#endif /* GL_NV_texture_border_clamp */ + +#ifndef GL_NV_texture_compression_s3tc_update +#define GL_NV_texture_compression_s3tc_update 1 +#endif /* GL_NV_texture_compression_s3tc_update */ + +#ifndef GL_NV_texture_npot_2D_mipmap +#define GL_NV_texture_npot_2D_mipmap 1 +#endif /* GL_NV_texture_npot_2D_mipmap */ + +#ifndef GL_QCOM_alpha_test +#define GL_QCOM_alpha_test 1 +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); +#endif +#endif /* GL_QCOM_alpha_test */ + +#ifndef GL_QCOM_binning_control +#define GL_QCOM_binning_control 1 +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#endif /* GL_QCOM_binning_control */ + +#ifndef GL_QCOM_driver_control +#define GL_QCOM_driver_control 1 +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); +GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); +GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); +#endif +#endif /* GL_QCOM_driver_control */ + +#ifndef GL_QCOM_extended_get +#define GL_QCOM_extended_get 1 +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC +typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures); +GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels); +GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, void **params); +#endif +#endif /* GL_QCOM_extended_get */ + +#ifndef GL_QCOM_extended_get2 +#define GL_QCOM_extended_get2 1 +typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders); +GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program); +GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif +#endif /* GL_QCOM_extended_get2 */ + +#ifndef GL_QCOM_perfmon_global_mode +#define GL_QCOM_perfmon_global_mode 1 +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#endif /* GL_QCOM_perfmon_global_mode */ + +#ifndef GL_QCOM_tiled_rendering +#define GL_QCOM_tiled_rendering 1 +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); +#endif +#endif /* GL_QCOM_tiled_rendering */ + +#ifndef GL_QCOM_writeonly_rendering +#define GL_QCOM_writeonly_rendering 1 +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#endif /* GL_QCOM_writeonly_rendering */ + +#ifndef GL_VIV_shader_binary +#define GL_VIV_shader_binary 1 +#define GL_SHADER_BINARY_VIV 0x8FC4 +#endif /* GL_VIV_shader_binary */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/opengldummy/3rdparty/include/GLES2/gl2platform.h b/tools/opengldummy/3rdparty/include/GLES2/gl2platform.h new file mode 100644 index 0000000000..89d4d44dc1 --- /dev/null +++ b/tools/opengldummy/3rdparty/include/GLES2/gl2platform.h @@ -0,0 +1,30 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +#include <KHR/khrplatform.h> + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl2platform_h_ */ diff --git a/tools/opengldummy/3rdparty/include/GLES3/gl3.h b/tools/opengldummy/3rdparty/include/GLES3/gl3.h new file mode 100644 index 0000000000..81b63bd03b --- /dev/null +++ b/tools/opengldummy/3rdparty/include/GLES3/gl3.h @@ -0,0 +1,937 @@ +#ifndef __gl3_h_ +#define __gl3_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision$ on $Date$ +*/ + +#include <GLES3/gl3platform.h> + +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: [23]\.[0-9] + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_ES_VERSION_2_0 +#define GL_ES_VERSION_2_0 1 +#include <KHR/khrplatform.h> +typedef khronos_int8_t GLbyte; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef short GLshort; +typedef unsigned short GLushort; +typedef void GLvoid; +typedef struct __GLsync *GLsync; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef unsigned int GLenum; +typedef unsigned int GLuint; +typedef char GLchar; +typedef khronos_float_t GLfloat; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +typedef unsigned int GLbitfield; +typedef int GLint; +typedef unsigned char GLboolean; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_NONE 0 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif /* GL_ES_VERSION_2_0 */ + +#ifndef GL_ES_VERSION_3_0 +#define GL_ES_VERSION_3_0 1 +typedef unsigned short GLhalf; +#define GL_READ_BUFFER 0x0C02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_RED 0x1903 +#define GL_RGB8 0x8051 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_RG8 0x822B +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +GL_APICALL void GL_APIENTRY glReadBuffer (GLenum mode); +GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQuery (GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); +GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GL_APICALL void GL_APIENTRY glEndTransformFeedback (void); +GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index); +GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id); +GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); +GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void); +GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif /* GL_ES_VERSION_3_0 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/opengldummy/3rdparty/include/GLES3/gl31.h b/tools/opengldummy/3rdparty/include/GLES3/gl31.h new file mode 100644 index 0000000000..6fe473d818 --- /dev/null +++ b/tools/opengldummy/3rdparty/include/GLES3/gl31.h @@ -0,0 +1,1184 @@ +#ifndef __gl31_h_ +#define __gl31_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision$ on $Date$ +*/ + +#include <GLES3/gl3platform.h> + +/* Generated on date 20140319 */ + +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2.[0-9]|3.[01] + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_ES_VERSION_2_0 +#define GL_ES_VERSION_2_0 1 +#include <KHR/khrplatform.h> +typedef khronos_int8_t GLbyte; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef short GLshort; +typedef unsigned short GLushort; +typedef void GLvoid; +typedef struct __GLsync *GLsync; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef unsigned int GLenum; +typedef unsigned int GLuint; +typedef char GLchar; +typedef khronos_float_t GLfloat; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +typedef unsigned int GLbitfield; +typedef int GLint; +typedef unsigned char GLboolean; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_NONE 0 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif /* GL_ES_VERSION_2_0 */ + +#ifndef GL_ES_VERSION_3_0 +#define GL_ES_VERSION_3_0 1 +typedef unsigned short GLhalf; +#define GL_READ_BUFFER 0x0C02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_RED 0x1903 +#define GL_RGB8 0x8051 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_RG8 0x822B +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +GL_APICALL void GL_APIENTRY glReadBuffer (GLenum mode); +GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQuery (GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); +GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GL_APICALL void GL_APIENTRY glEndTransformFeedback (void); +GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index); +GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id); +GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); +GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void); +GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif /* GL_ES_VERSION_3_0 */ + +#ifndef GL_ES_VERSION_3_1 +#define GL_ES_VERSION_3_1 1 +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_STENCIL_INDEX 0x1901 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +GL_APICALL void GL_APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GL_APICALL void GL_APIENTRY glDispatchComputeIndirect (GLintptr indirect); +GL_APICALL void GL_APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); +GL_APICALL void GL_APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); +GL_APICALL void GL_APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +GL_APICALL GLuint GL_APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); +GL_APICALL void GL_APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); +GL_APICALL void GL_APIENTRY glBindProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glValidateProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +GL_APICALL void GL_APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); +GL_APICALL void GL_APIENTRY glMemoryBarrier (GLbitfield barriers); +GL_APICALL void GL_APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); +GL_APICALL void GL_APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GL_APICALL void GL_APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); +GL_APICALL void GL_APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); +GL_APICALL void GL_APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GL_APICALL void GL_APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GL_APICALL void GL_APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GL_APICALL void GL_APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); +GL_APICALL void GL_APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); +#endif /* GL_ES_VERSION_3_1 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/opengldummy/3rdparty/include/GLES3/gl3platform.h b/tools/opengldummy/3rdparty/include/GLES3/gl3platform.h new file mode 100644 index 0000000000..b1e869dd11 --- /dev/null +++ b/tools/opengldummy/3rdparty/include/GLES3/gl3platform.h @@ -0,0 +1,30 @@ +#ifndef __gl3platform_h_ +#define __gl3platform_h_ + +/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 3.X gl3.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +#include <KHR/khrplatform.h> + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl3platform_h_ */ diff --git a/tools/opengldummy/3rdparty/include/KHR/khrplatform.h b/tools/opengldummy/3rdparty/include/KHR/khrplatform.h new file mode 100644 index 0000000000..d976ab546b --- /dev/null +++ b/tools/opengldummy/3rdparty/include/KHR/khrplatform.h @@ -0,0 +1,298 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include <KHR/khrplatform.h> + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +/* QtGlesStream */ +#ifdef QGS_BUILD_CLIENT_DLL +# define KHRONOS_APICALL __declspec(dllexport) +#else +# define KHRONOS_APICALL __declspec(dllimport) +#endif +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using <stdint.h> + */ +#include <stdint.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using <inttypes.h> + */ +#include <inttypes.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include <stdint.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +#if 1 + +/* QtGlesStream */ +#include <stddef.h> +typedef ptrdiff_t khronos_intptr_t; +typedef ptrdiff_t khronos_ssize_t; + +#else + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/tools/opengldummy/README b/tools/opengldummy/README new file mode 100644 index 0000000000..c8ca2dc726 --- /dev/null +++ b/tools/opengldummy/README @@ -0,0 +1,55 @@ +How to use the OpenGL dummy libraries + +The OpenGL Dummy libraries provide both headers and shared object files containing +the symbols for both OpenGL ES2 and EGL. The headers get copied into your sysroot +in the /usr/include folder, and the *.so file gets copied into your /usr/lib/ +folder in both the sysroot, as well as in the target image (distributed on the device). +The library that is generated contains all the symbols needed to succesffuly link +an application as if you had support for OpenGL ES2 and EGL. It is important to +make sure that you do not actually call any of these symbols in your application. + + +Installation: + +You need to have three things: + +Toolchain to cross compile code for your device +Sysroot containing development headers and shared objects to link against when +building applications +Target image inteded to be deployed to your device. + +1) Build the library + Setup your build environment by defining where your compiler and sysroot + are located: + eg. + export CC=/opt/arm-toolchain/usr/bin/arm-linux-gnueabi-g++ + export SYSROOT=/opt/device-name/sysroot/ + + Run the build script inside the client-dummy directory: + cd client-dummy + ./build-gcc.sh + + That should generate a two files: libEGL.so, libGLESv2.so + +2) Installation of files + Copy the include folder to the /usr/include folder in your sysroot. This + installs the OpenGL/EGL headers: + cp -r 3rdparty/include/* ${SYSROOT}/usr/include/ + + Copy libEGL.so and libGLESv2.so to the /usr/lib folder in your sysroot: + cp src/lib*.so ${SYSROOT}/usr/lib/ + + Copy the libEGL.so and libGLESv2.so to the target device image and/or device + (this is the copy that is linked against on the device). + +3) Build Qt against this fake OpenGL library + When configuring Qt, make sure to build with es2 support: + ./configure -opengl es2 ... + + Build as normal. + +4) Done + Now when you deploy your Qt build to the device it will depend on the dummy + libs libEGL.so and libGLESv2.so, but as long as you are using the Qt Quick + 2D Renderer plugin you will be able to use QtQuick2 without actually making + any OpenGL/EGL calls. diff --git a/tools/opengldummy/src/build-gcc.sh b/tools/opengldummy/src/build-gcc.sh new file mode 100755 index 0000000000..687807d1a6 --- /dev/null +++ b/tools/opengldummy/src/build-gcc.sh @@ -0,0 +1,3 @@ +#!/bin/sh +${CC} -DQGS_BUILD_CLIENT_DLL -fPIC -shared --sysroot ${SYSROOT} -I../3rdparty/include -o libEGL.so egl.cpp +${CC} -DQGS_BUILD_CLIENT_DLL -fPIC -shared --sysroot ${SYSROOT} -I../3rdparty/include -o libGLESv2.so gles2.cpp diff --git a/tools/opengldummy/src/egl.cpp b/tools/opengldummy/src/egl.cpp new file mode 100644 index 0000000000..d24f2f30ff --- /dev/null +++ b/tools/opengldummy/src/egl.cpp @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <EGL/egl.h> + +extern "C" { + +EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint * attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) +{ + return 0; +} + +EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint * attrib_list) +{ + return 0; +} + +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list) +{ + return 0; +} + +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list) +{ + return 0; +} + +EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config) +{ + return 0; +} + +EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay() +{ + return 0; +} + +EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) +{ + return 0; +} + +EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id) +{ + return 0; +} + +EGLAPI EGLint EGLAPIENTRY eglGetError() +{ + return 0; +} + +EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char * procname) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) +{ + return 0; +} + +EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL() +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval) +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api) +{ + return 0; +} + +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint * attrib_list) +{ + return 0; +} + +EGLAPI EGLenum EGLAPIENTRY eglQueryAPI() +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread() +{ + return 0; +} + +EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient() +{ + return 0; +} + +EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext() +{ + return 0; +} + +} // extern "C" + diff --git a/tools/opengldummy/src/gles2.cpp b/tools/opengldummy/src/gles2.cpp new file mode 100644 index 0000000000..d02dc79016 --- /dev/null +++ b/tools/opengldummy/src/gles2.cpp @@ -0,0 +1,765 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <GLES2/gl2.h> + +extern "C" { + +GL_APICALL void GL_APIENTRY glActiveTexture(GLenum texture) +{ + +} + +GL_APICALL void GL_APIENTRY glAttachShader(GLuint program, GLuint shader) +{ + +} + +GL_APICALL void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar * name) +{ + +} + +GL_APICALL void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer) +{ + +} + +GL_APICALL void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer) +{ + +} + +GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer) +{ + +} + +GL_APICALL void GL_APIENTRY glBindTexture(GLenum target, GLuint texture) +{ + +} + +GL_APICALL void GL_APIENTRY glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + +} + +GL_APICALL void GL_APIENTRY glBlendEquation(GLenum mode) +{ + +} + +GL_APICALL void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ + +} + +GL_APICALL void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) +{ + +} + +GL_APICALL void GL_APIENTRY glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +{ + +} + +GL_APICALL void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const void * data, GLenum usage) +{ + +} + +GL_APICALL void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void * data) +{ + +} + +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target) +{ + return 0; +} + +GL_APICALL void GL_APIENTRY glClear(GLbitfield mask) +{ + +} + +GL_APICALL void GL_APIENTRY glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + +} + +GL_APICALL void GL_APIENTRY glClearDepthf(GLfloat d) +{ + +} + +GL_APICALL void GL_APIENTRY glClearStencil(GLint s) +{ + +} + +GL_APICALL void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + +} + +GL_APICALL void GL_APIENTRY glCompileShader(GLuint shader) +{ + +} + +GL_APICALL void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data) +{ + +} + +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data) +{ + +} + +GL_APICALL void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ + +} + +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + +} + +GL_APICALL GLuint GL_APIENTRY glCreateProgram() +{ + return 0; +} + +GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type) +{ + return 0; +} + +GL_APICALL void GL_APIENTRY glCullFace(GLenum mode) +{ + +} + +GL_APICALL void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint * buffers) +{ + +} + +GL_APICALL void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint * framebuffers) +{ + +} + +GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program) +{ + +} + +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint * renderbuffers) +{ + +} + +GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader) +{ + +} + +GL_APICALL void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint * textures) +{ + +} + +GL_APICALL void GL_APIENTRY glDepthFunc(GLenum func) +{ + +} + +GL_APICALL void GL_APIENTRY glDepthMask(GLboolean flag) +{ + +} + +GL_APICALL void GL_APIENTRY glDepthRangef(GLfloat n, GLfloat f) +{ + +} + +GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader) +{ + +} + +GL_APICALL void GL_APIENTRY glDisable(GLenum cap) +{ + +} + +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray(GLuint index) +{ + +} + +GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) +{ + +} + +GL_APICALL void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void * indices) +{ + +} + +GL_APICALL void GL_APIENTRY glEnable(GLenum cap) +{ + +} + +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray(GLuint index) +{ + +} + +GL_APICALL void GL_APIENTRY glFinish() +{ + +} + +GL_APICALL void GL_APIENTRY glFlush() +{ + +} + +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +{ + +} + +GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +{ + +} + +GL_APICALL void GL_APIENTRY glFrontFace(GLenum mode) +{ + +} + +GL_APICALL void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers) +{ + +} + +GL_APICALL void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers) +{ + +} + +GL_APICALL void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) +{ + +} + +GL_APICALL void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures) +{ + +} + +GL_APICALL void GL_APIENTRY glGenerateMipmap(GLenum target) +{ + +} + +GL_APICALL void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) +{ + +} + +GL_APICALL void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) +{ + +} + +GL_APICALL void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) +{ + +} + +GL_APICALL GLint GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar * name) +{ + return 0; +} + +GL_APICALL void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* data) +{ + +} + +GL_APICALL void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + +} + +GL_APICALL GLenum GL_APIENTRY glGetError() +{ + return 0; +} + +GL_APICALL void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* data) +{ + +} + +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) +{ + +} + +GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* data) +{ + +} + +GL_APICALL void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) +{ + +} + +GL_APICALL void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params) +{ + +} + +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + +} + +GL_APICALL void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) +{ + +} + +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +{ + +} + +GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source) +{ + +} + +GL_APICALL void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params) +{ + +} + +GL_APICALL const GLubyte * GL_APIENTRY glGetString(GLenum name) +{ + return 0; +} + +GL_APICALL void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) +{ + +} + +GL_APICALL void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) +{ + +} + +GL_APICALL GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar * name) +{ + return 0; +} + +GL_APICALL void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params) +{ + +} + +GL_APICALL void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params) +{ + +} + +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, void ** pointer) +{ + +} + +GL_APICALL void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) +{ + +} + +GL_APICALL void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) +{ + +} + +GL_APICALL void GL_APIENTRY glHint(GLenum target, GLenum mode) +{ + +} + +GL_APICALL GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) +{ + return 0; +} + +GL_APICALL GLboolean GL_APIENTRY glIsEnabled(GLenum cap) +{ + return 0; +} + +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer) +{ + return 0; +} + +GL_APICALL GLboolean GL_APIENTRY glIsProgram(GLuint program) +{ + return 0; +} + +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer) +{ + return 0; +} + +GL_APICALL GLboolean GL_APIENTRY glIsShader(GLuint shader) +{ + return 0; +} + +GL_APICALL GLboolean GL_APIENTRY glIsTexture(GLuint texture) +{ + return 0; +} + +GL_APICALL void GL_APIENTRY glLineWidth(GLfloat width) +{ + +} + +GL_APICALL void GL_APIENTRY glLinkProgram(GLuint program) +{ + +} + +GL_APICALL void GL_APIENTRY glPixelStorei(GLenum pname, GLint param) +{ + +} + +GL_APICALL void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units) +{ + +} + +GL_APICALL void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels) +{ + +} + +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler() +{ + +} + +GL_APICALL void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +{ + +} + +GL_APICALL void GL_APIENTRY glSampleCoverage(GLfloat value, GLboolean invert) +{ + +} + +GL_APICALL void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ + +} + +GL_APICALL void GL_APIENTRY glShaderBinary(GLsizei count, const GLuint * shaders, GLenum binaryformat, const void * binary, GLsizei length) +{ + +} + +GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length) +{ + +} + +GL_APICALL void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask) +{ + +} + +GL_APICALL void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +{ + +} + +GL_APICALL void GL_APIENTRY glStencilMask(GLuint mask) +{ + +} + +GL_APICALL void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask) +{ + +} + +GL_APICALL void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) +{ + +} + +GL_APICALL void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) +{ + +} + +GL_APICALL void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels) +{ + +} + +GL_APICALL void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param) +{ + +} + +GL_APICALL void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat * params) +{ + +} + +GL_APICALL void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) +{ + +} + +GL_APICALL void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint * params) +{ + +} + +GL_APICALL void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform1f(GLint location, GLfloat v0) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform1i(GLint location, GLint v0) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform2f(GLint location, GLfloat v0, GLfloat v1) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform2i(GLint location, GLint v0, GLint v1) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform3i(GLint location, GLint v0, GLint v1, GLint v2) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + +} + +GL_APICALL void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) +{ + +} + +GL_APICALL void GL_APIENTRY glUseProgram(GLuint program) +{ + +} + +GL_APICALL void GL_APIENTRY glValidateProgram(GLuint program) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat * v) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat * v) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat * v) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat * v) +{ + +} + +GL_APICALL void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer) +{ + +} + +GL_APICALL void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + +} + +GL_APICALL void GL_APIENTRY glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +{ + +} + +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +{ + +} + +} // extern "C" + diff --git a/tools/qmleasing/mainwindow.cpp b/tools/qmleasing/mainwindow.cpp index e45feea76e..5a5f651396 100644 --- a/tools/qmleasing/mainwindow.cpp +++ b/tools/qmleasing/mainwindow.cpp @@ -29,7 +29,6 @@ #include "mainwindow.h" #include "splineeditor.h" #include <QtQuick/QQuickView> -#include <QtQuick> #include <QtQml/QQmlContext> #include <QEasingCurve> #include <QHBoxLayout> diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index c892f60680..1185a8e7ae 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -361,7 +361,7 @@ static void usage() puts(" "); exit(1); } - +#ifndef QT_NO_OPENGL // Listen on GL context creation of the QQuickWindow in order to print diagnostic output. class DiagnosticGlContextCreationListener : public QObject { Q_OBJECT @@ -389,7 +389,9 @@ private slots: context->doneCurrent(); deleteLater(); } + }; +#endif static void setWindowTitle(bool verbose, const QObject *topLevel, QWindow *window) { @@ -403,8 +405,10 @@ static void setWindowTitle(bool verbose, const QObject *topLevel, QWindow *windo if (verbose) { newTitle += QLatin1String(" [Qt ") + QLatin1String(QT_VERSION_STR) + QLatin1Char(' ') + QGuiApplication::platformName() + QLatin1Char(' '); +#ifndef QT_NO_OPENGL newTitle += QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL ? QLatin1String("GL") : QLatin1String("GLES"); +#endif newTitle += QLatin1Char(']'); } if (oldTitle != newTitle) @@ -592,8 +596,10 @@ int main(int argc, char ** argv) if (window) { setWindowTitle(options.verbose, topLevel, window.data()); +#ifndef QT_NO_OPENGL if (options.verbose) new DiagnosticGlContextCreationListener(window.data()); +#endif QSurfaceFormat surfaceFormat = window->requestedFormat(); if (options.multisample) surfaceFormat.setSamples(16); |