| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441 |
- /****************************************************************************
- *
- * Copyright 2012 - 2023 Vivante Corporation, Santa Clara, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS 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
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *****************************************************************************/
- #include "vg_lite_context.h"
- /* Path data operations. */
- #define CDALIGN(value, by) (((value) + (by) - 1) & ~((by) - 1))
- #define CDMIN(x, y) ((x) > (y) ? (y) : (x))
- #define CDMAX(x, y) ((x) > (y) ? (x) : (y))
- extern uint32_t transform(vg_lite_point_t* result, vg_lite_float_t x, vg_lite_float_t y, vg_lite_matrix_t* matrix);
- extern uint32_t convert_blend(vg_lite_blend_t blend);
- extern uint32_t inverse(vg_lite_matrix_t* result, vg_lite_matrix_t* matrix);
- extern uint32_t convert_yuv2rgb(vg_lite_yuv2rgb_t yuv);
- extern uint32_t convert_uv_swizzle(vg_lite_swizzle_t swizzle);
- extern uint32_t convert_source_format(vg_lite_buffer_format_t format);
- extern vg_lite_error_t check_compress(vg_lite_buffer_format_t format, vg_lite_compress_mode_t compress_mode, vg_lite_buffer_layout_t tiled, uint32_t width, uint32_t height);
- extern void get_format_bytes(vg_lite_buffer_format_t format, uint32_t* mul, uint32_t* div, uint32_t* bytes_align);
- extern vg_lite_error_t srcbuf_align_check(vg_lite_buffer_t* source);
- extern vg_lite_matrix_t identity_mtx;
- /* Convert VGLite data format to HW value. */
- static uint32_t convert_path_format(vg_lite_format_t format)
- {
- switch (format) {
- case VG_LITE_S8:
- return 0;
-
- case VG_LITE_S16:
- return 0x100000;
-
- case VG_LITE_S32:
- return 0x200000;
-
- case VG_LITE_FP32:
- return 0x300000;
-
- default:
- return 0;
- }
- }
- /* Convert VGLite quality enums to HW values. */
- static uint32_t convert_path_quality(vg_lite_quality_t quality)
- {
- switch (quality) {
- case VG_LITE_HIGH:
- return 0x3;
-
- case VG_LITE_UPPER:
- return 0x2;
-
- case VG_LITE_MEDIUM:
- return 0x1;
-
- default:
- return 0x0;
- }
- }
- static int32_t get_data_count(uint8_t cmd)
- {
- static int32_t count[] = {
- 0,
- 0,
- 2,
- 2,
- 2,
- 2,
- 4,
- 4,
- 6,
- 6,
- 0,
- 1,
- 1,
- 1,
- 1,
- 2,
- 2,
- 4,
- 4,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5,
- 5
- };
- if (cmd > VLC_OP_LCWARC_REL) {
- return -1;
- }
- else {
- return count[cmd];
- }
- }
- static void compute_pathbounds(float* xmin, float* ymin, float* xmax, float* ymax, float x, float y)
- {
- if (xmin != NULL)
- {
- *xmin = *xmin < x ? *xmin : x;
- }
- if (xmax != NULL)
- {
- *xmax = *xmax > x ? *xmax : x;
- }
- if (ymin != NULL)
- {
- *ymin = *ymin < y ? *ymin : y;
- }
- if (ymax != NULL)
- {
- *ymax = *ymax > y ? *ymax : y;
- }
- }
- int32_t get_data_size(vg_lite_format_t format)
- {
- int32_t data_size = 0;
- switch (format) {
- case VG_LITE_S8:
- data_size = sizeof(int8_t);
- break;
- case VG_LITE_S16:
- data_size = sizeof(int16_t);
- break;
- case VG_LITE_S32:
- data_size = sizeof(int32_t);
- break;
- default:
- data_size = sizeof(vg_lite_float_t);
- break;
- }
- return data_size;
- }
- vg_lite_error_t vg_lite_init_path(vg_lite_path_t* path,
- vg_lite_format_t data_format,
- vg_lite_quality_t quality,
- vg_lite_uint32_t path_length,
- vg_lite_pointer path_data,
- vg_lite_float_t min_x, vg_lite_float_t min_y,
- vg_lite_float_t max_x, vg_lite_float_t max_y)
- {
- int32_t data_size, num = 0;
- if (path == NULL)
- return VG_LITE_INVALID_ARGUMENT;
- memset(path, 0, sizeof(*path));
- path->format = data_format;
- path->quality = quality;
- path->bounding_box[0] = min_x;
- path->bounding_box[1] = min_y;
- path->bounding_box[2] = max_x;
- path->bounding_box[3] = max_y;
- /* Path data cannot end with a CLOSE op. Replace CLOSE with END for path_data */
- data_size = get_data_size(data_format);
- num = path_length / data_size;
- switch (data_format)
- {
- case VG_LITE_S8:
- if (path_data && (*((char*)path_data + num - 1) == VLC_OP_CLOSE))
- {
- *(char*)((int*)path_data + num - 1) = VLC_OP_END;
- }
- break;
- case VG_LITE_S16:
- if (path_data && (*(char*)((short*)path_data + num - 1) == VLC_OP_CLOSE))
- {
- *(char*)((short*)path_data + num - 1) = VLC_OP_END;
- }
- break;
- case VG_LITE_S32:
- if (path_data && (*(char*)((int*)path_data + num - 1) == VLC_OP_CLOSE))
- {
- *(char*)((int*)path_data + num - 1) = VLC_OP_END;
- }
- break;
- case VG_LITE_FP32:
- if (path_data && (*(char*)((float*)path_data + num - 1) == VLC_OP_CLOSE))
- {
- *(char*)((float*)path_data + num - 1) = VLC_OP_END;
- }
- break;
- default:
- break;
- }
- path->path_length = path_length;
- path->path = path_data;
- path->path_changed = 1;
- path->uploaded.address = 0;
- path->uploaded.bytes = 0;
- path->uploaded.handle = NULL;
- path->uploaded.memory = NULL;
- path->pdata_internal = 0;
- s_context.path_lastX = 0;
- s_context.path_lastY = 0;
- /* Default FILL path type*/
- path->path_type = VG_LITE_DRAW_FILL_PATH;
- return VG_LITE_SUCCESS;
- }
- vg_lite_error_t vg_lite_set_path_type(vg_lite_path_t* path, vg_lite_path_type_t path_type)
- {
- if (!path ||
- (path_type != VG_LITE_DRAW_FILL_PATH &&
- path_type != VG_LITE_DRAW_STROKE_PATH &&
- path_type != VG_LITE_DRAW_FILL_STROKE_PATH)
- )
- return VG_LITE_INVALID_ARGUMENT;
- path->path_type = path_type;
- return VG_LITE_SUCCESS;
- }
- vg_lite_error_t vg_lite_clear_path(vg_lite_path_t* path)
- {
- vg_lite_error_t error;
- if (path->uploaded.handle != NULL) {
- vg_lite_kernel_free_t free_cmd;
- free_cmd.memory_handle = path->uploaded.handle;
- error = vg_lite_kernel(VG_LITE_FREE, &free_cmd);
- if (error != VG_LITE_SUCCESS)
- return error;
- }
- #if (CHIPID==0x355)
- if (path->stroke && path->stroke->uploaded.handle != NULL) {
- vg_lite_kernel_free_t free_cmd;
- free_cmd.memory_handle = path->stroke->uploaded.handle;
- error = vg_lite_kernel(VG_LITE_FREE, &free_cmd);
- if (error != VG_LITE_SUCCESS)
- return error;
- }
- #endif
- path->uploaded.address = 0;
- path->uploaded.bytes = 0;
- path->uploaded.handle = NULL;
- path->uploaded.memory = NULL;
- #if (CHIPID==0x355)
- if (path->stroke) {
- path->stroke->uploaded.address = 0;
- path->stroke->uploaded.bytes = 0;
- path->stroke->uploaded.handle = NULL;
- path->stroke->uploaded.memory = NULL;
- }
- #endif
- if (path->pdata_internal == 1 && path->path != NULL) {
- vg_lite_os_free(path->path);
- }
- path->path = NULL;
- if (path->stroke_path) {
- vg_lite_os_free(path->stroke_path);
- path->stroke_path = NULL;
- }
- #if gcFEATURE_VG_STROKE_PATH
- if (path->stroke) {
- if (path->stroke->path_list_divide) {
- vg_lite_path_list_ptr cur_list;
- while (path->stroke->path_list_divide) {
- cur_list = path->stroke->path_list_divide->next;
- if (path->stroke->path_list_divide->path_points) {
- vg_lite_path_point_ptr temp_point;
- while (path->stroke->path_list_divide->path_points) {
- temp_point = path->stroke->path_list_divide->path_points->next;
- vg_lite_os_free(path->stroke->path_list_divide->path_points);
- path->stroke->path_list_divide->path_points = temp_point;
- }
- temp_point = NULL;
- }
- vg_lite_os_free(path->stroke->path_list_divide);
- path->stroke->path_list_divide = cur_list;
- }
- cur_list = 0;
- }
- if (path->stroke->stroke_paths) {
- vg_lite_sub_path_ptr temp_sub_path;
- while (path->stroke->stroke_paths) {
- temp_sub_path = path->stroke->stroke_paths->next;
- if (path->stroke->stroke_paths->point_list) {
- vg_lite_path_point_ptr temp_point;
- while (path->stroke->stroke_paths->point_list) {
- temp_point = path->stroke->stroke_paths->point_list->next;
- vg_lite_os_free(path->stroke->stroke_paths->point_list);
- path->stroke->stroke_paths->point_list = temp_point;
- }
- temp_point = NULL;
- }
- vg_lite_os_free(path->stroke->stroke_paths);
- path->stroke->stroke_paths = temp_sub_path;
- }
- temp_sub_path = NULL;
- }
- if (path->stroke->dash_pattern)
- vg_lite_os_free(path->stroke->dash_pattern);
- vg_lite_os_free(path->stroke);
- path->stroke = NULL;
- path->stroke_valid = 0;
- path->stroke_size = 0;
- }
- #endif
- return VG_LITE_SUCCESS;
- }
- vg_lite_error_t vg_lite_upload_path(vg_lite_path_t * path)
- {
- #if DUMP_API
- FUNC_DUMP(vg_lite_upload_path)(path);
- #endif
- vg_lite_error_t error = VG_LITE_SUCCESS;
- uint32_t bytes;
- vg_lite_buffer_t Buf, *buffer;
- buffer = &Buf;
- /* Compute the number of bytes required for path + command buffer prefix/postfix. */
- bytes = (8 + path->path_length + 7 + 8) & ~7;
- /* Allocate GPU memory. */
- buffer->width = bytes;
- buffer->height = 1;
- buffer->stride = 0;
- buffer->format = VG_LITE_A8;
- VG_LITE_RETURN_ERROR(vg_lite_allocate(buffer));
- /* Initialize command buffer prefix. */
- ((uint32_t *) buffer->memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8);
- ((uint32_t *) buffer->memory)[1] = 0;
-
- /* Copy the path data. */
- memcpy((uint32_t *) buffer->memory + 2, path->path, path->path_length);
- /* Initialize command buffer postfix. */
- ((uint32_t *) buffer->memory)[(bytes >> 2) - 2] = VG_LITE_RETURN();
- ((uint32_t *) buffer->memory)[(bytes >> 2) - 1] = 0;
- /* Mark path as uploaded. */
- path->path = buffer->memory;
- path->uploaded.handle = buffer->handle;
- path->uploaded.address = buffer->address;
- path->uploaded.memory = buffer->memory;
- path->uploaded.bytes = bytes;
- path->path_changed = 0;
- VLM_PATH_ENABLE_UPLOAD(*path); /* Implicitly enable path uploading. */
-
- /* Return pointer to vg_lite_buffer structure. */
- return error;
- }
- vg_lite_uint32_t vg_lite_get_path_length(vg_lite_uint8_t *cmd, vg_lite_uint32_t count, vg_lite_format_t format)
- {
- uint32_t size = 0;
- int32_t dCount = 0;
- uint32_t i = 0;
- int32_t data_size = 0;
-
- data_size = get_data_size(format);
-
- for (i = 0; i < count; i++) {
- size++; /* OP CODE. */
-
- dCount = get_data_count(cmd[i]);
- size = CDALIGN(size, data_size);
- size += dCount * data_size;
- }
- if (cmd[count - 1] != VLC_OP_END || cmd[count - 1] != VLC_OP_CLOSE) {
- size++;
- size = CDALIGN(size, data_size);
- }
-
- return size;
- }
- vg_lite_error_t vg_lite_append_path(vg_lite_path_t *path,
- vg_lite_uint8_t *cmd,
- vg_lite_pointer data,
- vg_lite_uint32_t seg_count)
- {
- vg_lite_error_t error = VG_LITE_SUCCESS;
- uint32_t i;
- int32_t j;
- int32_t offset = 0;
- int32_t dataCount = 0;
- float *dataf = (float*) data;
- float *pathf = NULL;
- int32_t *data_s32 = (int32_t*) data;
- int32_t *path_s32 = NULL;
- int16_t *data_s16 = (int16_t*) data;
- int16_t *path_s16 = NULL;
- int8_t *data_s8 = (int8_t*) data;
- int8_t *path_s8 = NULL;
- uint8_t *pathc = NULL;
- int32_t data_size;
- uint8_t arc_path = 0;
- uint8_t h_v_path = 0;
- uint8_t smooth_path = 0;
- float px = 0.0f, py = 0.0f, cx = 0.0f, cy = 0.0f;
- int rel = 0;
- if (cmd == NULL || data == NULL || path == NULL)
- return VG_LITE_INVALID_ARGUMENT;
- for(i = 0; i < seg_count; i++) {
- if (cmd[i] > VLC_OP_LCWARC_REL)
- return VG_LITE_INVALID_ARGUMENT;
- }
- /* Support NULL path->path case for OpenVG */
- if (!path->path) {
- data_size = vg_lite_get_path_length(cmd, seg_count, path->format);
- path->path = (vg_lite_pointer)vg_lite_os_malloc(data_size);
- if (!path->path)
- {
- return VG_LITE_OUT_OF_RESOURCES;
- }
- path->pdata_internal = 1;
- memset(path->path, 0, data_size);
- }
- data_size = get_data_size(path->format);
- path->path_changed= 1;
- pathf = (float *)path->path;
- path_s32 = (int32_t *)path->path;
- path_s16 = (int16_t *)path->path;
- path_s8 = (int8_t *)path->path;
- pathc = (uint8_t *)path->path;
- /* Set bounding box if the first opcode is VLC_OP_MOVE_* */
- if ((cmd[0] & 0xfe) == VLC_OP_MOVE) {
- switch (path->format)
- {
- case VG_LITE_S8:
- cx = (float)data_s8[0];
- cy = (float)data_s8[1];
- break;
- case VG_LITE_S16:
- cx = (float)data_s16[0];
- cy = (float)data_s16[1];
- break;
- case VG_LITE_S32:
- cx = (float)data_s32[0];
- cy = (float)data_s32[1];
- break;
- case VG_LITE_FP32:
- cx = (float)dataf[0];
- cy = (float)dataf[1];
- break;
- }
- path->bounding_box[0] = path->bounding_box[2] = cx;
- path->bounding_box[1] = path->bounding_box[3] = cy;
- }
- /* Loop to fill path data. */
- for (i = 0; i < seg_count; i++) {
- #if (CHIPID == 0x355)
- if (cmd[i] == VLC_OP_CLOSE && (cmd[i + 1] == VLC_OP_MOVE || cmd[i + 1] == VLC_OP_MOVE_REL)) {
- continue;
- }
- else
- #endif
- {
- *(pathc + offset) = cmd[i];
- }
- offset++;
- dataCount = get_data_count(cmd[i]);
- /* compute the bounding_box. */
- if (dataCount >= 0) {
- offset = CDALIGN(offset, data_size);
- if ((cmd[i] > VLC_OP_CLOSE) &&
- (cmd[i] < VLC_OP_HLINE) &&
- ((cmd[i] & 0x01) == 1)) {
- rel = 1;
- }
- else if ((cmd[i] >= VLC_OP_HLINE) &&
- ((cmd[i] & 0x01) == 0)) {
- rel = 1;
- }
- else {
- rel = 0;
- }
- if (cmd[i] >= VLC_OP_HLINE && cmd[i] <= VLC_OP_VLINE_REL) {
- switch (path->format) {
- case VG_LITE_S8:
- path_s8 = (int8_t*)(pathc + offset);
- path_s8[0] = *data_s8;
- data_s8++;
- if (rel) {
- cx = px + (float)path_s8[0];
- cy = py + (float)path_s8[1];
- }
- else {
- cx = (float)path_s8[0];
- cy = (float)path_s8[1];
- }
- break;
- case VG_LITE_S16:
- path_s16 = (int16_t*)(pathc + offset);
- path_s16[0] = *data_s16;
- data_s16++;
- if (rel) {
- cx = px + (float)path_s16[0];
- cy = py + (float)path_s16[1];
- }
- else {
- cx = (float)path_s16[0];
- cy = (float)path_s16[1];
- }
- break;
- case VG_LITE_S32:
- path_s32 = (int32_t*)(pathc + offset);
- path_s32[0] = *data_s32;
- data_s32++;
- if (rel) {
- cx = px + (float)path_s32[0];
- cy = py + (float)path_s32[1];
- }
- else {
- cx = (float)path_s32[0];
- cy = (float)path_s32[1];
- }
- break;
- case VG_LITE_FP32:
- pathf = (float*)(pathc + offset);
- pathf[0] = *dataf;
- dataf++;
- if (rel) {
- cx = px + (float)pathf[0];
- cy = py + (float)pathf[1];
- }
- else {
- cx = (float)pathf[0];
- cy = (float)pathf[1];
- }
- break;
- }
- h_v_path = 1;
- /* Update path bounds. */
- path->bounding_box[0] = CDMIN(path->bounding_box[0], cx);
- path->bounding_box[2] = CDMAX(path->bounding_box[2], cx);
- path->bounding_box[1] = CDMIN(path->bounding_box[1], cy);
- path->bounding_box[3] = CDMAX(path->bounding_box[3], cy);
- }
- else if (cmd[i] < VLC_OP_SCCWARC) {
- /* Mark smooth path,convert it in next step. */
- if (cmd[i] <= VLC_OP_SCUBIC_REL && cmd[i] >= VLC_OP_SQUAD) {
- smooth_path = 1;
- }
- for (j = 0; j < dataCount / 2; j++) {
- switch (path->format) {
- case VG_LITE_S8:
- path_s8 = (int8_t *)(pathc + offset);
- path_s8[j * 2] = *data_s8;
- data_s8++;
- path_s8[j * 2 + 1] = *data_s8;
- data_s8++;
- if (rel) {
- cx = px + path_s8[j * 2];
- cy = py + path_s8[j * 2 + 1];
- }
- else {
- cx = path_s8[j * 2];
- cy = path_s8[j * 2 + 1];
- }
- break;
- case VG_LITE_S16:
- path_s16 = (int16_t *)(pathc + offset);
- path_s16[j * 2] = *data_s16;
- data_s16++;
- path_s16[j * 2 + 1] = *data_s16;
- data_s16++;
- if (rel) {
- cx = px + path_s16[j * 2];
- cy = py + path_s16[j * 2 + 1];
- }
- else {
- cx = path_s16[j * 2];
- cy = path_s16[j * 2 + 1];
- }
- break;
- case VG_LITE_S32:
- path_s32 = (int32_t *)(pathc + offset);
- path_s32[j * 2] = *data_s32;
- data_s32++;
- path_s32[j * 2 + 1] = *data_s32;
- data_s32++;
- if (rel) {
- cx = px + path_s32[j * 2];
- cy = py + path_s32[j * 2 + 1];
- }
- else {
- cx = (float)path_s32[j * 2];
- cy = (float)path_s32[j * 2 + 1];
- }
- break;
- case VG_LITE_FP32:
- pathf = (float *)(pathc + offset);
- pathf[j * 2] = *dataf;
- dataf++;
- pathf[j * 2 + 1] = *dataf;
- dataf++;
- if (rel) {
- cx = px + pathf[j * 2];
- cy = py + pathf[j * 2 + 1];
- }
- else {
- cx = pathf[j * 2];
- cy = pathf[j * 2 + 1];
- }
- break;
- default:
- return VG_LITE_INVALID_ARGUMENT;
- }
- if (cmd[i] <= VLC_OP_LINE_REL && cmd[i] >= VLC_OP_MOVE) {
- /* Update move to and line path bounds. */
- path->bounding_box[0] = CDMIN(path->bounding_box[0], cx);
- path->bounding_box[2] = CDMAX(path->bounding_box[2], cx);
- path->bounding_box[1] = CDMIN(path->bounding_box[1], cy);
- path->bounding_box[3] = CDMAX(path->bounding_box[3], cy);
- }
- }
- }
- #if gcFEATURE_VG_ARC_PATH
- else {
- arc_path = 1;
- switch (path->format) {
- case VG_LITE_S8:
- path_s8 = (int8_t*)(pathc + offset);
- path_s8[0] = *data_s8;
- data_s8++;
- path_s8[1] = *data_s8;
- data_s8++;
- path_s8[2] = *data_s8;
- data_s8++;
- path_s8[3] = *data_s8;
- data_s8++;
- path_s8[4] = *data_s8;
- data_s8++;
- if (rel) {
- cx = px + path_s8[3];
- cy = py + path_s8[4];
- }
- else {
- cx = path_s8[3];
- cy = path_s8[4];
- }
- /* Update path bounds. */
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx + 2 * path_s8[0],cy + 2 * path_s8[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px + 2 * path_s8[1],py + 2 * path_s8[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx - 2 * path_s8[0],cy - 2 * path_s8[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px - 2 * path_s8[1],py - 2 * path_s8[1]);
- break;
- case VG_LITE_S16:
- path_s16 = (int16_t*)(pathc + offset);
- path_s16[0] = *data_s16;
- data_s16++;
- path_s16[1] = *data_s16;
- data_s16++;
- path_s16[2] = *data_s16;
- data_s16++;
- path_s16[3] = *data_s16;
- data_s16++;
- path_s16[4] = *data_s16;
- data_s16++;
- if (rel) {
- cx = px + path_s16[3];
- cy = py + path_s16[4];
- }
- else {
- cx = path_s16[3];
- cy = path_s16[4];
- }
- /* Update path bounds. */
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx + 2 * path_s16[0],cy + 2 * path_s16[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px + 2 * path_s16[1],py + 2 * path_s16[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx - 2 * path_s16[0],cy - 2 * path_s16[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px - 2 * path_s16[1],py - 2 * path_s16[1]);
- break;
- case VG_LITE_S32:
- path_s32 = (int32_t*)(pathc + offset);
- path_s32[0] = *data_s32;
- data_s32++;
- path_s32[1] = *data_s32;
- data_s32++;
- path_s32[2] = *data_s32;
- data_s32++;
- path_s32[3] = *data_s32;
- data_s32++;
- path_s32[4] = *data_s32;
- data_s32++;
- if (rel) {
- cx = px + path_s32[3];
- cy = py + path_s32[4];
- }
- else {
- cx = (float)path_s32[3];
- cy = (float)path_s32[4];
- }
- /* Update path bounds. */
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx + 2 * path_s32[0],cy + 2 * path_s32[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px + 2 * path_s32[1],py + 2 * path_s32[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx - 2 * path_s32[0],cy - 2 * path_s32[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px - 2 * path_s32[1],py - 2 * path_s32[1]);
- break;
- case VG_LITE_FP32:
- pathf = (float*)(pathc + offset);
- pathf[0] = *dataf;
- dataf++;
- pathf[1] = *dataf;
- dataf++;
- pathf[2] = *dataf;
- dataf++;
- pathf[3] = *dataf;
- dataf++;
- pathf[4] = *dataf;
- dataf++;
- if (rel) {
- cx = px + pathf[3];
- cy = py + pathf[4];
- }
- else {
- cx = pathf[3];
- cy = pathf[4];
- }
- /* Update path bounds. */
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx + 2 * pathf[0],cy + 2 * pathf[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px + 2 * pathf[1],py + 2 * pathf[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],cx - 2 * pathf[0],cy - 2 * pathf[1]);
- compute_pathbounds(&path->bounding_box[0], &path->bounding_box[1], &path->bounding_box[2], &path->bounding_box[3],px - 2 * pathf[1],py - 2 * pathf[1]);
- break;
- }
- }
- #endif
- px = cx;
- py = cy;
- offset += dataCount * data_size;
- }
- }
- if (cmd[seg_count - 1] == VLC_OP_END
- #if gcFEATURE_VG_ARC_PATH
- || (cmd[seg_count - 1] == VLC_OP_CLOSE && (arc_path | h_v_path | smooth_path))
- #endif
- ) {
- path->path_length = offset;
- }
- else {
- path->path_length = offset + data_size;
- path->add_end = 1;
- ((uint8_t*)(path->path))[offset] = 0;
- }
- #if gcFEATURE_VG_ARC_PATH
- if (arc_path | h_v_path | smooth_path) {
- error = vg_lite_init_arc_path(path,
- path->format,
- path->quality,
- path->path_length,
- path->path,
- path->bounding_box[0], path->bounding_box[1],
- path->bounding_box[2], path->bounding_box[3]);
- }
- #endif
- s_context.path_lastX = cx;
- s_context.path_lastY = cy;
- return error;
- }
- #if (CHIPID==0x355 || CHIPID==0x255) /* GC355/GC255 vg_lite_draw functions */
- #define UPDATE_BOUNDING_BOX(bbx, point) \
- do { \
- if ((point).x < (bbx).x) { \
- (bbx).width += (bbx).x - (point).x; \
- (bbx).x = (point).x; \
- } \
- if ((point).y < (bbx).y) { \
- (bbx).height += (bbx).y - (point).y; \
- (bbx).y = (point).y; \
- } \
- if ((point).x > (bbx).x + (bbx).width) \
- (bbx).width = (point).x - (bbx).x; \
- if ((point).y > (bbx).y + (bbx).height) \
- (bbx).height = (point).y - (bbx).y; \
- } while(0)
- static vg_lite_error_t transform_bounding_box(vg_lite_rectangle_t *in_bbx,
- vg_lite_matrix_t *matrix,
- vg_lite_rectangle_t *clip,
- vg_lite_rectangle_t *out_bbx,
- vg_lite_point_t *origin)
- {
- vg_lite_point_t temp;
- memset(out_bbx, 0, sizeof(vg_lite_rectangle_t));
- /* Transform image point (0, 0). */
- if (!transform(&temp, 0.0f, 0.0f, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- out_bbx->x = temp.x;
- out_bbx->y = temp.y;
- /* Provide position of the new origin to the caller if requested. */
- if (origin != NULL) {
- origin->x = temp.x;
- origin->y = temp.y;
- }
- /* Transform image point (0, height). */
- if (!transform(&temp, 0.0f, (vg_lite_float_t)in_bbx->height, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- UPDATE_BOUNDING_BOX(*out_bbx, temp);
- /* Transform image point (width, height). */
- if (!transform(&temp, (vg_lite_float_t)in_bbx->width, (vg_lite_float_t)in_bbx->height, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- UPDATE_BOUNDING_BOX(*out_bbx, temp);
- /* Transform image point (width, 0). */
- if (!transform(&temp, (vg_lite_float_t)in_bbx->width, 0.0f, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- UPDATE_BOUNDING_BOX(*out_bbx, temp);
- /* Clip is required */
- if (clip) {
- out_bbx->x = MAX(out_bbx->x, clip->x);
- out_bbx->y = MAX(out_bbx->y, clip->y);
- out_bbx->width = MIN((out_bbx->x + out_bbx->width), (clip->x + clip->width)) - out_bbx->x;
- out_bbx->height = MIN((out_bbx->y + out_bbx->height), (clip->y + clip->height)) - out_bbx->y;
- }
- return VG_LITE_SUCCESS;
- }
- static vg_lite_error_t set_interpolation_steps(vg_lite_buffer_t *target,
- vg_lite_int32_t s_width,
- vg_lite_int32_t s_height,
- vg_lite_matrix_t *matrix)
- {
- vg_lite_matrix_t im;
- vg_lite_rectangle_t src_bbx, bounding_box, clip;
- vg_lite_float_t xs[3], ys[3], cs[3];
- vg_lite_error_t error = VG_LITE_SUCCESS;
- float dx = 0.0f, dy = 0.0f;
- #define ERR_LIMIT 0.0000610351562f
- /* Get bounding box. */
- memset(&src_bbx, 0, sizeof(vg_lite_rectangle_t));
- memset(&clip, 0, sizeof(vg_lite_rectangle_t));
- src_bbx.width = (int32_t)s_width;
- src_bbx.height = (int32_t)s_height;
- if (s_context.scissor_set) {
- clip.x = s_context.scissor[0];
- clip.y = s_context.scissor[1];
- clip.width = s_context.scissor[2];
- clip.height = s_context.scissor[3];
- } else {
- clip.x = clip.y = 0;
- clip.width = s_context.rtbuffer->width;
- clip.height = s_context.rtbuffer->height;
- }
- transform_bounding_box(&src_bbx, matrix, &clip, &bounding_box, NULL);
- /* Compute inverse matrix. */
- if (!inverse(&im, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- /* Compute interpolation steps. */
- /* X step */
- xs[0] = im.m[0][0] / s_width;
- xs[1] = im.m[1][0] / s_height;
- xs[2] = im.m[2][0];
- /* Y step */
- ys[0] = im.m[0][1] / s_width;
- ys[1] = im.m[1][1] / s_height;
- ys[2] = im.m[2][1];
- /* C step 2 */
- cs[2] = 0.5f * (im.m[2][0] + im.m[2][1]) + im.m[2][2];
- /* C step 0, 1*/
- cs[0] = (0.5f * (im.m[0][0] + im.m[0][1]) + im.m[0][2] + dx) / s_width;
- cs[1] = (0.5f * (im.m[1][0] + im.m[1][1]) + im.m[1][2] + dy) / s_height;
- /* Set command buffer */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *)&cs[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *)&cs[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *)&cs[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *)&xs[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *)&xs[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *)&xs[2]));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *)&ys[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *)&ys[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *)&ys[2]));
- return VG_LITE_SUCCESS;
- }
- static vg_lite_error_t set_interpolation_steps_draw_paint(vg_lite_buffer_t* target,
- vg_lite_int32_t s_width,
- vg_lite_int32_t s_height,
- vg_lite_matrix_t* matrix)
- {
- vg_lite_matrix_t im;
- vg_lite_rectangle_t src_bbx, bounding_box, clip;
- vg_lite_float_t xs[3], ys[3], cs[3];
- vg_lite_error_t error = VG_LITE_SUCCESS;
- float dx = 0.0f, dy = 0.0f;
- #define ERR_LIMIT 0.0000610351562f
- /* Get bounding box. */
- memset(&src_bbx, 0, sizeof(vg_lite_rectangle_t));
- memset(&clip, 0, sizeof(vg_lite_rectangle_t));
- src_bbx.width = (int32_t)s_width;
- src_bbx.height = (int32_t)s_height;
- if (s_context.scissor_set) {
- clip.x = s_context.scissor[0];
- clip.y = s_context.scissor[1];
- clip.width = s_context.scissor[2];
- clip.height = s_context.scissor[3];
- }
- else {
- clip.x = clip.y = 0;
- clip.width = s_context.rtbuffer->width;
- clip.height = s_context.rtbuffer->height;
- }
- transform_bounding_box(&src_bbx, matrix, &clip, &bounding_box, NULL);
- /* Compute inverse matrix. */
- if (!inverse(&im, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- /* Compute interpolation steps. */
- /* X step */
- xs[0] = im.m[0][0] / s_width;
- xs[1] = im.m[1][0] / s_height;
- xs[2] = im.m[2][0];
- /* Y step */
- ys[0] = im.m[0][1] / s_width;
- ys[1] = im.m[1][1] / s_height;
- ys[2] = im.m[2][1];
- /* C step 2 */
- cs[2] = 0.5f * (im.m[2][0] + im.m[2][1]) + im.m[2][2];
- /* C step 0, 1*/
- cs[0] = (0.5f * (im.m[0][0] + im.m[0][1]) + im.m[0][2] + dx) / s_width;
- cs[1] = (0.5f * (im.m[1][0] + im.m[1][1]) + im.m[1][2] + dy) / s_height;
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A04, (void*)&cs[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A05, (void*)&cs[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A06, (void*)&xs[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A07, (void*)&xs[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A08, (void*)&ys[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A09, (void*)&ys[1]));
- /* Set command buffer */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void*)&cs[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void*)&cs[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void*)&cs[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void*)&xs[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void*)&xs[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void*)&xs[2]));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void*)&ys[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void*)&ys[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void*)&ys[2]));
- return VG_LITE_SUCCESS;
- }
- /* GC355/GC255 vg_lite_draw API implementation
- */
- vg_lite_error_t vg_lite_draw(vg_lite_buffer_t *target,
- vg_lite_path_t *path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t * matrix,
- vg_lite_blend_t blend,
- vg_lite_color_t color)
- {
- uint32_t blend_mode;
- uint32_t format, quality, tiling, fill;
- uint32_t tessellation_size;
- vg_lite_error_t error;
- int32_t dst_align_width;
- uint32_t mul, div, align;
- vg_lite_point_t point_min = {0}, point_max = {0}, temp = {0};
- int x, y, width, height;
- uint8_t ts_is_fullscreen = 0;
- uint32_t in_premult = 0;
- uint32_t premul_flag = 0;
- uint32_t prediv_flag = 0;
- #if(CHIPID == 0x355)
- uint8_t *path_re = NULL;
- uint32_t index = 0;
- #endif
- #if gcFEATURE_VG_TRACE_API
- VGLITE_LOG("vg_lite_draw %p %p %d %p %d 0x%08X\n", target, path, fill_rule, matrix, blend, color);
- VGLITE_LOG(" path_type %d, path_length %d, stroke_size %d\n", path->path_type, path->path_length, path->stroke_size);
- #endif
- #if gcFEATURE_VG_ERROR_CHECK
- #if !gcFEATURE_VG_QUALITY_8X
- if (path->quality == VG_LITE_UPPER) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- if (!path || !path->path) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- #if (CHIPID == 0x355)
- if (target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV ||
- target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 ||
- target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) {
- printf("Target format: 0x%x is not supported.\n", target->format);
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #endif /* gcFEATURE_VG_ERROR_CHECK */
- if (!path->path_length) {
- return VG_LITE_SUCCESS;
- }
- if (!matrix) {
- matrix = &identity_mtx;
- }
- #if gcFEATURE_VG_GAMMA
- set_gamma_dest_only(target, VGL_FALSE);
- #endif
- /*blend input into context*/
- s_context.blend_mode = blend;
- /* Adjust premultiply setting according to openvg condition */
- target->apply_premult = 0;
- premul_flag = (s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE);
- if (target->premultiplied == 0 && premul_flag == 0) {
- in_premult = 0x10000000;
- target->apply_premult = 1;
- }
- else if ((target->premultiplied == 1) ||
- (target->premultiplied == 0 && premul_flag == 1)) {
- in_premult = 0x00000000;
- }
- if (blend == VG_LITE_BLEND_NORMAL_LVGL) {
- in_premult = 0x00000000;
- }
- error = set_render_target(target);
- if (error != VG_LITE_SUCCESS) {
- return error;
- } else if (error == VG_LITE_NO_CONTEXT) {
- /* If scissoring is enabled and no valid scissoring rectangles
- are present, no drawing occurs */
- return VG_LITE_SUCCESS;
- }
- width = s_context.tessbuf.tess_w_h & 0xFFFF;
- height = s_context.tessbuf.tess_w_h >> 16;
- get_format_bytes(target->format, &mul, &div, &align);
- dst_align_width = target->stride * div / mul;
- if (width == 0 || height == 0)
- return VG_LITE_NO_CONTEXT;
- if ((dst_align_width <= width) && (target->height <= height))
- {
- ts_is_fullscreen = 1;
- point_min.x = 0;
- point_min.y = 0;
- point_max.x = dst_align_width;
- point_max.y = target->height;
- }
- if (ts_is_fullscreen == 0){
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix);
- point_min = point_max = temp;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- if (point_min.x < 0) point_min.x = 0;
- if (point_min.y < 0) point_min.y = 0;
- if (point_max.x > dst_align_width) point_max.x = dst_align_width;
- if (point_max.y > target->height) point_max.y = target->height;
- if (s_context.scissor_set) {
- point_min.x = MAX(point_min.x, s_context.scissor[0]);
- point_min.y = MAX(point_min.y, s_context.scissor[1]);
- point_max.x = MIN(point_max.x, s_context.scissor[0] + s_context.scissor[2]);
- point_max.y = MIN(point_max.y, s_context.scissor[1] + s_context.scissor[3]);
- }
- }
- /* Convert states into hardware values. */
- blend_mode = convert_blend(blend);
- format = convert_path_format(path->format);
- quality = convert_path_quality(path->quality);
- tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0;
- fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0;
- tessellation_size = s_context.tessbuf.L2_size ? s_context.tessbuf.L2_size : s_context.tessbuf.L1_size;
- /* Setup the command buffer. */
- /* Program color register. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, in_premult | s_context.capabilities.cap.tiled | blend_mode | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color));
- /* Program tessellation control: for TS module. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */
- /* Program matrix. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &matrix->m[0][0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &matrix->m[0][1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &matrix->m[0][2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &matrix->m[1][0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &matrix->m[1][1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &matrix->m[1][2]));
- /* Setup tessellation loop. */
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH)
- {
- for (y = point_min.y; y < point_max.y; y += height) {
- for (x = point_min.x; x < point_max.x; x += width) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 15));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- }
- }
- }
- }
- /* Setup tessellation loop. */
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- for (y = point_min.y; y < point_max.y; y += height) {
- for (x = point_min.x; x < point_max.x; x += width) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 15));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- if (VLM_PATH_STROKE_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->stroke->uploaded.address, path->stroke->uploaded.bytes));
- }
- else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- }
- }
- }
- /* Finialize command buffer. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0));
- return error;
- }
- /* GC355/GC255 vg_lite_draw_pattern API implementation
- */
- vg_lite_error_t vg_lite_draw_pattern(vg_lite_buffer_t *target,
- vg_lite_path_t *path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t *path_matrix,
- vg_lite_buffer_t *source,
- vg_lite_matrix_t *pattern_matrix,
- vg_lite_blend_t blend,
- vg_lite_pattern_mode_t pattern_mode,
- vg_lite_color_t pattern_color,
- vg_lite_color_t color,
- vg_lite_filter_t filter)
- {
- vg_lite_error_t error = VG_LITE_SUCCESS;
- uint32_t imageMode;
- uint32_t blend_mode;
- uint32_t filter_mode = 0;
- int32_t dst_align_width;
- uint32_t mul, div, align;
- uint32_t conversion = 0;
- uint32_t tiled_source;
- vg_lite_matrix_t matrix;
- uint32_t pattern_tile = 0;
- uint32_t transparency_mode = 0;
-
- /* The following code is from "draw path" */
- uint32_t format, quality, tiling, fill;
- uint32_t tessellation_size;
- vg_lite_point_t point_min = {0}, point_max = {0}, temp = {0};
- int x, y, width, height;
- uint8_t ts_is_fullscreen = 0;
- uint32_t in_premult = 0;
- uint32_t src_premultiply_enable = 0;
- uint32_t paintType = 0;
- uint32_t premul_flag = 0;
- uint32_t prediv_flag = 0;
- uint8_t lvgl_sw_blend = 0;
- #if(CHIPID == 0X355)
- uint8_t* path_re = NULL;
- uint32_t index = 0;
- #endif
- #if gcFEATURE_VG_TRACE_API
- VGLITE_LOG("vg_lite_draw_pattern %p %p %d %p %p %p %d %d 0x%08X %d\n",
- target, path, fill_rule, path_matrix, source, pattern_matrix, blend, pattern_mode, pattern_color, filter);
- #endif
- #if gcFEATURE_VG_ERROR_CHECK
- #if !gcFEATURE_VG_QUALITY_8X
- if (path->quality == VG_LITE_UPPER) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- if (source->format == VG_LITE_A4 || source->format == VG_LITE_A8) {
- return VG_LITE_NOT_SUPPORT;
- }
- if (!path || !path->path) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- #if (CHIPID == 0x355)
- if (target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV ||
- target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 ||
- target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) {
- printf("Target format: 0x%x is not supported.\n", target->format);
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #endif /* gcFEATURE_VG_ERROR_CHECK */
- #if !gcFEATURE_VG_LVGL_SUPPORT
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- if (!source->lvgl_buffer) {
- source->lvgl_buffer = (vg_lite_buffer_t *)vg_lite_os_malloc(sizeof(vg_lite_buffer_t));
- *source->lvgl_buffer = *source;
- source->lvgl_buffer->lvgl_buffer = NULL;
- vg_lite_allocate(source->lvgl_buffer);
- }
- /* Make sure render target is up to date before reading RT. */
- vg_lite_finish();
- setup_lvgl_image(target, source, source->lvgl_buffer, blend);
- blend = VG_LITE_BLEND_SRC_OVER;
- lvgl_sw_blend = 1;
- }
- #endif
- if (!path->path_length) {
- return VG_LITE_SUCCESS;
- }
- if (!path_matrix) {
- path_matrix = &identity_mtx;
- }
- if (!pattern_matrix) {
- pattern_matrix = &identity_mtx;
- }
- /* Work on pattern states. */
- matrix = *pattern_matrix;
- if (source->paintType == VG_LITE_PAINT_PATTERN)
- {
- matrix.m[2][0] = 0;
- matrix.m[2][1] = 0;
- matrix.m[2][2] = 1;
- source->image_mode = VG_LITE_NONE_IMAGE_MODE;
- }
- #if gcFEATURE_VG_GAMMA
- save_st_gamma_src_dest(source, target);
- #endif
- /*blend input into context*/
- s_context.blend_mode = blend;
- in_premult = 0x00000000;
- /* Adjust premultiply setting according to openvg condition */
- src_premultiply_enable = 0x01000100;
- if (s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 &&
- (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) {
- prediv_flag = 0;
- }
- else {
- prediv_flag = 1;
- }
- if ((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || source->image_mode == VG_LITE_STENCIL_MODE) {
- premul_flag = 1;
- }
- else {
- premul_flag = 0;
- }
- if ((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x10000000;
- }
- /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */
- else if (source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 0 && target->premultiplied == 1) ||
- (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- if ((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && blend <= VG_LITE_BLEND_SUBTRACT) {
- in_premult = 0x00000000;
- }
- if (blend == VG_LITE_BLEND_NORMAL_LVGL) {
- in_premult = 0x00000000;
- }
- if (source->premultiplied == target->premultiplied && premul_flag == 0) {
- target->apply_premult = 1;
- }
- else {
- target->apply_premult = 0;
- }
- error = set_render_target(target);
- if (error != VG_LITE_SUCCESS) {
- return error;
- } else if (error == VG_LITE_NO_CONTEXT) {
- /* If scissoring is enabled and no valid scissoring rectangles
- are present, no drawing occurs */
- return VG_LITE_SUCCESS;
- }
- transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000:0);
- width = s_context.tessbuf.tess_w_h & 0xFFFF;
- height = s_context.tessbuf.tess_w_h >> 16;
- get_format_bytes(target->format, &mul, &div, &align);
- dst_align_width = target->stride * div / mul;
- if (width == 0 || height == 0)
- return VG_LITE_NO_CONTEXT;
- if ((dst_align_width <= width) && (target->height <= height))
- {
- ts_is_fullscreen = 1;
- point_min.x = 0;
- point_min.y = 0;
- point_max.x = dst_align_width;
- point_max.y = target->height;
- }
- /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */
- if ((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) {
- conversion = 0x80000000;
- }
- /* Determine image mode (NORMAL or MULTIPLY) depending on the color. */
- imageMode = (source->image_mode == VG_LITE_NONE_IMAGE_MODE) ? 0 : (source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE) ? 0x00002000 : 0x00001000;
- tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ;
-
- if (pattern_mode == VG_LITE_PATTERN_COLOR)
- {
- uint8_t a,r,g,b;
- pattern_tile = 0;
- a = pattern_color >> 24;
- r = pattern_color >> 16;
- g = pattern_color >> 8;
- b = pattern_color;
- pattern_color = (a << 24) | (b << 16) | (g << 8) | r;
- }
- else if (pattern_mode == VG_LITE_PATTERN_PAD)
- {
- pattern_tile = 0x1000;
- }
- #if gcFEATURE_VG_IM_REPEAT_REFLECT
- else if (pattern_mode == VG_LITE_PATTERN_REPEAT)
- {
- pattern_tile = 0x2000;
- }
- else if (pattern_mode == VG_LITE_PATTERN_REFLECT)
- {
- pattern_tile = 0x3000;
- }
- #endif
- else
- {
- return VG_LITE_INVALID_ARGUMENT;
- }
- switch (filter) {
- case VG_LITE_FILTER_POINT:
- filter_mode = 0;
- break;
- case VG_LITE_FILTER_LINEAR:
- filter_mode = 0x10000;
- break;
- case VG_LITE_FILTER_BI_LINEAR:
- filter_mode = 0x20000;
- break;
- case VG_LITE_FILTER_GAUSSIAN:
- filter_mode = 0x30000;
- break;
- }
- if (source->paintType == VG_LITE_PAINT_PATTERN)
- {
- VG_LITE_RETURN_ERROR(set_interpolation_steps_draw_paint(target, source->width, source->height, &matrix));
- /* enable pre-multiplied in image unit */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) |
- filter_mode | pattern_tile | conversion | src_premultiply_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, pattern_color));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, source->stride | tiled_source));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width | (source->height << 16)));
- }
- else
- {
- VG_LITE_RETURN_ERROR(set_interpolation_steps(target, source->width, source->height, &matrix));
- /* enable pre-multiplied in image unit */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, convert_source_format(source->format) |
- filter_mode | pattern_tile | conversion | src_premultiply_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A27, pattern_color));
- #if !gcFEATURE_VG_LVGL_SUPPORT
- if (lvgl_sw_blend) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->lvgl_buffer->address));
- }
- else
- #endif
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->address));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, source->stride | tiled_source));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2D, 0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2F, source->width | (source->height << 16)));
- }
- /* Work on path states. */
- matrix = *path_matrix;
- if (ts_is_fullscreen == 0){
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], &matrix);
- point_min = point_max = temp;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], &matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], &matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], &matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
-
- point_min.x = MAX(point_min.x, 0);
- point_min.y = MAX(point_min.y, 0);
- point_max.x = MIN(point_max.x, dst_align_width);
- point_max.y = MIN(point_max.y, target->height);
- if (s_context.scissor_set) {
- point_min.x = MAX(point_min.x, s_context.scissor[0]);
- point_min.y = MAX(point_min.y, s_context.scissor[1]);
- point_max.x = MIN(point_max.x, s_context.scissor[0] + s_context.scissor[2]);
- point_max.y = MIN(point_max.y, s_context.scissor[1] + s_context.scissor[3]);
- }
- }
- /* Convert states into hardware values. */
- blend_mode = convert_blend(blend);
- format = convert_path_format(path->format);
- quality = convert_path_quality(path->quality);
- tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0;
- fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0;
- tessellation_size = s_context.tessbuf.L2_size ? s_context.tessbuf.L2_size : s_context.tessbuf.L1_size;
- /* Setup the command buffer. */
- /* Program color register. */
- if (source->paintType == VG_LITE_PAINT_PATTERN) {
- paintType = 1 << 24 | 1 << 25;
- }
- /* enable pre-multiplied from VG to VGPE */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, 0x2 | in_premult | paintType | s_context.capabilities.cap.tiled | imageMode | blend_mode | transparency_mode | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000400 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */
- /* Program matrix. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &matrix.m[0][0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &matrix.m[0][1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &matrix.m[0][2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &matrix.m[1][0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &matrix.m[1][1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &matrix.m[1][2]));
- /* Setup tessellation loop. */
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH)
- {
- for (y = point_min.y; y < point_max.y; y += height) {
- for (x = point_min.x; x < point_max.x; x += width) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 15));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- }
- }
- }
- }
- /* Setup tessellation loop. */
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- for (y = point_min.y; y < point_max.y; y += height) {
- for (x = point_min.x; x < point_max.x; x += width) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 15));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- if (VLM_PATH_STROKE_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->stroke->uploaded.address, path->stroke->uploaded.bytes));
- }
- else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- }
- }
- }
- /* Finialize command buffer. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0));
- vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride)* (source->height));
- return error;
- }
- /* GC355/GC255 vg_lite_draw_linear_grad API implementation
- */
- vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t * target,
- vg_lite_path_t * path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t * path_matrix,
- vg_lite_linear_gradient_ext_t *grad,
- vg_lite_color_t paint_color,
- vg_lite_blend_t blend,
- vg_lite_filter_t filter)
- {
- vg_lite_error_t error = VG_LITE_SUCCESS;
- uint32_t image_mode;
- uint32_t blend_mode;
- uint32_t filter_mode = 0;
- uint32_t conversion = 0;
- uint32_t tiled_source;
- int32_t dst_align_width;
- uint32_t mul, div, align;
- vg_lite_matrix_t inverse_matrix;
- vg_lite_buffer_t * source = &grad->image;
- vg_lite_matrix_t * matrix = &grad->matrix;
- uint32_t linear_tile = 0;
- uint32_t transparency_mode = 0;
- uint32_t in_premult = 0;
- uint32_t src_premultiply_enable = 0;
- uint32_t premul_flag = 0;
- uint32_t prediv_flag = 0;
- void *data;
- /* The following code is from "draw path" */
- uint32_t format, quality, tiling, fill;
- uint32_t tessellation_size;
- vg_lite_kernel_allocate_t memory;
- vg_lite_kernel_free_t free_memory;
- uint32_t return_offset = 0;
- vg_lite_point_t point_min = {0}, point_max = {0}, temp = {0};
- int x, y, width, height;
- uint8_t ts_is_fullscreen = 0;
- vg_lite_float_t dx, dy, dxdx_dydy;
- vg_lite_float_t lg_step_x_lin, lg_step_y_lin, lg_constant_lin;
- #if(CHIPID == 0X355)
- uint8_t* path_re = NULL;
- uint32_t index = 0;
- #endif
- #if gcFEATURE_VG_TRACE_API
- VGLITE_LOG("vg_lite_draw_linear_grad %p %p %d %p %p 0x%08X %d %d\n",
- target, path, fill_rule, path_matrix, grad, paint_color, blend, filter);
- #endif
- #if gcFEATURE_VG_ERROR_CHECK
- #if !gcFEATURE_VG_LVGL_SUPPORT
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_QUALITY_8X
- if (path->quality == VG_LITE_UPPER) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- if (source->format == VG_LITE_A4 || source->format == VG_LITE_A8) {
- return VG_LITE_NOT_SUPPORT;
- }
- if (!path || !path->path) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- #if (CHIPID == 0x355)
- if (target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV ||
- target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 ||
- target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) {
- printf("Target format: 0x%x is not supported.\n", target->format);
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #endif /* gcFEATURE_VG_ERROR_CHECK */
- if (!path_matrix) {
- path_matrix = &identity_mtx;
- }
- #if gcFEATURE_VG_GAMMA
- set_gamma_dest_only(target, VGL_TRUE);
- #endif
- /*blend input into context*/
- s_context.blend_mode = blend;
- src_premultiply_enable = 0x01000100;
- if (s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 &&
- (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) {
- prediv_flag = 0;
- }
- else {
- prediv_flag = 1;
- }
- if ((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || source->image_mode == VG_LITE_STENCIL_MODE) {
- premul_flag = 1;
- }
- else {
- premul_flag = 0;
- }
- if ((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x10000000;
- }
- /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */
- else if (source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 0 && target->premultiplied == 1) ||
- (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- if ((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && blend <= VG_LITE_BLEND_SUBTRACT) {
- #if (CHIPID==0x255)
- src_premultiply_enable = 0x00000000;
- #endif
- in_premult = 0x00000000;
- }
- if (blend == VG_LITE_BLEND_NORMAL_LVGL) {
- in_premult = 0x00000000;
- }
- if (source->premultiplied == target->premultiplied && premul_flag == 0) {
- target->apply_premult = 1;
- }
- else {
- target->apply_premult = 0;
- }
- error = set_render_target(target);
- if (error != VG_LITE_SUCCESS) {
- return error;
- } else if (error == VG_LITE_NO_CONTEXT) {
- /* If scissoring is enabled and no valid scissoring rectangles
- are present, no drawing occurs */
- return VG_LITE_SUCCESS;
- }
- transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000:0);
- width = s_context.tessbuf.tess_w_h & 0xFFFF;
- height = s_context.tessbuf.tess_w_h >> 16;
- get_format_bytes(target->format, &mul, &div, &align);
- dst_align_width = target->stride * div / mul;
- if (width == 0 || height == 0)
- return VG_LITE_NO_CONTEXT;
- if ((dst_align_width <= width) && (target->height <= height))
- {
- ts_is_fullscreen = 1;
- point_min.x = 0;
- point_min.y = 0;
- point_max.x = dst_align_width;
- point_max.y = target->height;
- }
- /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */
- if ((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) {
- conversion = 0x80000000;
- }
- /* Determine image mode (NORMAL or MULTIPLY) depending on the color. */
- image_mode = (source->image_mode == VG_LITE_NONE_IMAGE_MODE) ? 0 : (source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE) ? 0x00002000 : 0x00001000;
- tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ;
- switch (grad->spread_mode) {
- case VG_LITE_GRADIENT_SPREAD_FILL:
- linear_tile = 0x0;
- break;
- case VG_LITE_GRADIENT_SPREAD_PAD:
- linear_tile = 0x1000;
- break;
- case VG_LITE_GRADIENT_SPREAD_REPEAT:
- linear_tile = 0x2000;
- break;
- case VG_LITE_GRADIENT_SPREAD_REFLECT:
- linear_tile = 0x3000;
- break;
- }
- switch (filter) {
- case VG_LITE_FILTER_POINT:
- filter_mode = 0;
- break;
- case VG_LITE_FILTER_LINEAR:
- filter_mode = 0x10000;
- break;
- case VG_LITE_FILTER_BI_LINEAR:
- filter_mode = 0x20000;
- break;
- case VG_LITE_FILTER_GAUSSIAN:
- filter_mode = 0x30000;
- break;
- }
- if (grad->spread_mode == VG_LITE_GRADIENT_SPREAD_FILL)
- {
- uint8_t a,r,g,b;
- a = paint_color >> 24;
- r = paint_color >> 16;
- g = paint_color >> 8;
- b = paint_color;
- paint_color = (a << 24) | (b << 16) | (g << 8) | r;
- }
- /* compute radial gradient paremeters */
- /* Compute inverse matrix. */
- if (!inverse(&inverse_matrix, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- dx = grad->linear_grad.X1 - grad->linear_grad.X0;
- dy = grad->linear_grad.Y1 - grad->linear_grad.Y0;
- dxdx_dydy = dx * dx + dy * dy;
- /*
- ** dx (T(x) - x0) + dy (T(y) - y0)
- ** g = -------------------------------
- ** dx^2 + dy^2
- **
- ** where
- **
- ** dx := x1 - x0
- ** dy := y1 - y1
- ** T(x) := (x + 0.5) m00 + (y + 0.5) m01 + m02
- ** = x m00 + y m01 + 0.5 (m00 + m01) + m02
- ** T(y) := (x + 0.5) m10 + (y + 0.5) m11 + m12
- ** = x m10 + y m11 + 0.5 (m10 + m11) + m12.
- **
- ** We can factor the top line into:
- **
- ** = dx (x m00 + y m01 + 0.5 (m00 + m01) + m02 - x0)
- ** + dy (x m10 + y m11 + 0.5 (m10 + m11) + m12 - y0)
- **
- ** = x (dx m00 + dy m10)
- ** + y (dx m01 + dy m11)
- ** + dx (0.5 (m00 + m01) + m02 - x0)
- ** + dy (0.5 (m10 + m11) + m12 - y0).
- */
- lg_step_x_lin
- = (dx * MAT(&inverse_matrix, 0, 0) + dy * MAT(&inverse_matrix, 1, 0))
- / dxdx_dydy;
- lg_step_y_lin
- = (dx * MAT(&inverse_matrix, 0, 1) + dy * MAT(&inverse_matrix, 1, 1))
- / dxdx_dydy;
- lg_constant_lin =
- (
- (
- 0.5f * ( MAT(&inverse_matrix, 0, 0) + MAT(&inverse_matrix, 0, 1) )
- + MAT(&inverse_matrix, 0, 2) - grad->linear_grad.X0
- ) * dx
- +
- (
- 0.5f * ( MAT(&inverse_matrix, 1, 0) + MAT(&inverse_matrix, 1, 1) )
- + MAT(&inverse_matrix, 1, 2) - grad->linear_grad.Y0
- ) * dy
- )
- / dxdx_dydy;
- /* Setup the command buffer. */
- /* linear gradient parameters*/
- data = &lg_constant_lin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A04,*(uint32_t*) data));
- data = &lg_step_x_lin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A06,*(uint32_t*) data));
- data = &lg_step_y_lin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A08,*(uint32_t*) data));
- VG_LITE_RETURN_ERROR(set_interpolation_steps(target, source->width, source->height, matrix));
- /* enable pre-multiplied in image unit */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) |
- filter_mode | linear_tile | conversion | src_premultiply_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, paint_color));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, tiled_source));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width));
- /* Work on path states. */
- matrix = path_matrix;
- if (ts_is_fullscreen == 0){
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix);
- point_min = point_max = temp;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- point_min.x = MAX(point_min.x, 0);
- point_min.y = MAX(point_min.y, 0);
- point_max.x = MIN(point_max.x, dst_align_width);
- point_max.y = MIN(point_max.y, target->height);
- if (s_context.scissor_set) {
- point_min.x = MAX(point_min.x, s_context.scissor[0]);
- point_min.y = MAX(point_min.y, s_context.scissor[1]);
- point_max.x = MIN(point_max.x, s_context.scissor[0] + s_context.scissor[2]);
- point_max.y = MIN(point_max.y, s_context.scissor[1] + s_context.scissor[3]);
- }
- }
- /* Convert states into hardware values. */
- blend_mode = convert_blend(blend);
- format = convert_path_format(path->format);
- quality = convert_path_quality(path->quality);
- tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0;
- fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0;
- tessellation_size = s_context.tessbuf.L2_size ? s_context.tessbuf.L2_size : s_context.tessbuf.L1_size;
- /* Setup the command buffer. */
- /* Program color register. */
- /* enable pre-multiplied from VG to VGPE */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, 0x01000002 | s_context.capabilities.cap.tiled | in_premult | image_mode | blend_mode | transparency_mode | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000400 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */
- /* Program matrix. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &matrix->m[0][0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &matrix->m[0][1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &matrix->m[0][2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &matrix->m[1][0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &matrix->m[1][1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &matrix->m[1][2]));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1)
- {
- if (path->path_changed != 0) {
- if (path->uploaded.handle != NULL) {
- free_memory.memory_handle = path->uploaded.handle;
- vg_lite_kernel(VG_LITE_FREE, &free_memory);
- path->uploaded.address = 0;
- path->uploaded.memory = NULL;
- path->uploaded.handle = NULL;
- }
- /* Allocate memory for the path data. */
- memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8);
- return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4;
- memory.contiguous = 1;
- VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory));
- ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0;
- ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8);
- ((uint32_t *) memory.memory)[1] = 0;
- memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length);
- ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN();
- ((uint32_t *) memory.memory)[return_offset + 1] = 0;
- path->uploaded.handle = memory.memory_handle;
- path->uploaded.memory = memory.memory;
- path->uploaded.address = memory.memory_gpu;
- path->uploaded.bytes = memory.bytes;
- path->path_changed = 0;
- }
- }
- /* Setup tessellation loop. */
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) {
- for (y = point_min.y; y < point_max.y; y += height) {
- for (x = point_min.x; x < point_max.x; x += width) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 15));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- }
- }
- }
- }
- /* Setup tessellation loop. */
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- for (y = point_min.y; y < point_max.y; y += height) {
- for (x = point_min.x; x < point_max.x; x += width) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 15));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- if (VLM_PATH_STROKE_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->stroke->uploaded.address, path->stroke->uploaded.bytes));
- } else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- }
- }
- }
- /* Finialize command buffer. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0));
- return error;
- }
- /* GC355/GC255 vg_lite_draw_radial_grad API implementation
- */
- vg_lite_error_t vg_lite_draw_radial_grad(vg_lite_buffer_t * target,
- vg_lite_path_t * path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t * path_matrix,
- vg_lite_radial_gradient_t *grad,
- vg_lite_color_t paint_color,
- vg_lite_blend_t blend,
- vg_lite_filter_t filter)
- {
- vg_lite_error_t error = VG_LITE_SUCCESS;
- uint32_t imageMode;
- uint32_t blend_mode;
- uint32_t filter_mode = 0;
- uint32_t conversion = 0;
- uint32_t tiled_source;
- int32_t dst_align_width;
- uint32_t mul, div, align;
- vg_lite_matrix_t inverse_matrix;
- vg_lite_buffer_t * source = &grad->image;
- vg_lite_matrix_t * matrix = &grad->matrix;
- uint32_t rad_tile = 0;
- uint32_t transparency_mode = 0;
- uint32_t in_premult = 0;
- uint32_t src_premultiply_enable = 0;
- uint32_t premul_flag = 0;
- uint32_t prediv_flag = 0;
- void *data;
- /* The following code is from "draw path" */
- uint32_t format, quality, tiling, fill;
- uint32_t tessellation_size;
- vg_lite_kernel_allocate_t memory;
- vg_lite_kernel_free_t free_memory;
- uint32_t return_offset = 0;
- vg_lite_point_t point_min = {0}, point_max = {0}, temp = {0};
- int x, y, width, height;
- uint8_t ts_is_fullscreen = 0;
- vg_lite_float_t radius;
- vg_lite_float_t centerX, centerY;
- vg_lite_float_t focalX, focalY;
- vg_lite_float_t fx, fy;
- vg_lite_float_t fxfy_2;
- vg_lite_float_t radius2;
- vg_lite_float_t r2_fx2, r2_fy2;
- vg_lite_float_t r2_fx2_2, r2_fy2_2;
- vg_lite_float_t r2_fx2_fy2;
- vg_lite_float_t r2_fx2_fy2sq;
- vg_lite_float_t cx, cy;
- vg_lite_float_t rgConstantLin, rgStepXLin, rgStepYLin;
- vg_lite_float_t rgConstantRad, rgStepXRad, rgStepYRad;
- vg_lite_float_t rgStepXXRad, rgStepYYRad, rgStepXYRad;
- #if(CHIPID == 0X355)
- uint8_t* path_re = NULL;
- uint32_t index = 0;
- #endif
- #if gcFEATURE_VG_TRACE_API
- VGLITE_LOG("vg_lite_draw_radial_grad %p %p %d %p %p 0x%08X %d %d\n",
- target, path, fill_rule, path_matrix, grad, paint_color, blend, filter);
- #endif
- #if gcFEATURE_VG_ERROR_CHECK
- #if !gcFEATURE_VG_LVGL_SUPPORT
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_QUALITY_8X
- if (path->quality == VG_LITE_UPPER) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- if (source->format == VG_LITE_A4 || source->format == VG_LITE_A8) {
- return VG_LITE_NOT_SUPPORT;
- }
- if (!path || !path->path) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- #if (CHIPID == 0x355)
- if (target->format == VG_LITE_L8 || target->format == VG_LITE_YUYV ||
- target->format == VG_LITE_BGRA2222 || target->format == VG_LITE_RGBA2222 ||
- target->format == VG_LITE_ABGR2222 || target->format == VG_LITE_ARGB2222) {
- printf("Target format: 0x%x is not supported.\n", target->format);
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- radius = grad->radial_grad.r;
- if (radius < 0) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, source->height));
- #endif /* gcFEATURE_VG_ERROR_CHECK */
- if (!path->path_length) {
- return VG_LITE_SUCCESS;
- }
- if (!path_matrix) {
- path_matrix = &identity_mtx;
- }
- #if gcFEATURE_VG_GAMMA
- set_gamma_dest_only(target, VGL_TRUE);
- #endif
- /*blend input into context*/
- s_context.blend_mode = blend;
- src_premultiply_enable = 0x01000100;
- if (s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 &&
- (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) {
- prediv_flag = 0;
- }
- else {
- prediv_flag = 1;
- }
- if ((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || source->image_mode == VG_LITE_STENCIL_MODE) {
- premul_flag = 1;
- }
- else {
- premul_flag = 0;
- }
- if ((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x10000000;
- }
- /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */
- else if (source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 0 && target->premultiplied == 1) ||
- (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- if ((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && blend <= VG_LITE_BLEND_SUBTRACT) {
- #if (CHIPID==0x255)
- src_premultiply_enable = 0x00000000;
- #endif
- in_premult = 0x00000000;
- }
- if (blend == VG_LITE_BLEND_NORMAL_LVGL) {
- in_premult = 0x00000000;
- }
- if (source->premultiplied == target->premultiplied && premul_flag == 0) {
- target->apply_premult = 1;
- }
- else {
- target->apply_premult = 0;
- }
- error = set_render_target(target);
- if (error != VG_LITE_SUCCESS) {
- return error;
- } else if (error == VG_LITE_NO_CONTEXT) {
- /* If scissoring is enabled and no valid scissoring rectangles
- are present, no drawing occurs */
- return VG_LITE_SUCCESS;
- }
- transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000:0);
- width = s_context.tessbuf.tess_w_h & 0xFFFF;
- height = s_context.tessbuf.tess_w_h >> 16;
- get_format_bytes(target->format, &mul, &div, &align);
- dst_align_width = target->stride * div / mul;
- if (width == 0 || height == 0)
- return VG_LITE_NO_CONTEXT;
- if ((dst_align_width <= width) && (target->height <= height))
- {
- ts_is_fullscreen = 1;
- point_min.x = 0;
- point_min.y = 0;
- point_max.x = dst_align_width;
- point_max.y = target->height;
- }
- /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */
- if ((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) {
- conversion = 0x80000000;
- }
- /* Determine image mode (NORMAL or MULTIPLY) depending on the color. */
- imageMode = (source->image_mode == VG_LITE_NONE_IMAGE_MODE) ? 0 : (source->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE) ? 0x00002000 : 0x00001000;
- tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ;
- switch (grad->spread_mode) {
- case VG_LITE_GRADIENT_SPREAD_FILL:
- rad_tile = 0x0;
- break;
- case VG_LITE_GRADIENT_SPREAD_PAD:
- rad_tile = 0x1000;
- break;
- case VG_LITE_GRADIENT_SPREAD_REPEAT:
- rad_tile = 0x2000;
- break;
- case VG_LITE_GRADIENT_SPREAD_REFLECT:
- rad_tile = 0x3000;
- break;
- }
- switch (filter) {
- case VG_LITE_FILTER_POINT:
- filter_mode = 0;
- break;
- case VG_LITE_FILTER_LINEAR:
- filter_mode = 0x10000;
- break;
- case VG_LITE_FILTER_BI_LINEAR:
- filter_mode = 0x20000;
- break;
- case VG_LITE_FILTER_GAUSSIAN:
- filter_mode = 0x30000;
- break;
- }
- if (grad->spread_mode == VG_LITE_GRADIENT_SPREAD_FILL)
- {
- uint8_t a,r,g,b;
- a = paint_color >> 24;
- r = paint_color >> 16;
- g = paint_color >> 8;
- b = paint_color;
- paint_color = (a << 24) | (b << 16) | (g << 8) | r;
- }
- /* compute radial gradient paremeters */
- /* Compute inverse matrix. */
- if (!inverse(&inverse_matrix, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- /* Make shortcuts to the gradient information. */
- centerX = grad->radial_grad.cx;
- centerY = grad->radial_grad.cy;
- focalX = grad->radial_grad.fx;
- focalY = grad->radial_grad.fy;
- /* Compute constants of the equation. */
- fx = focalX - centerX;
- fy = focalY - centerY;
- radius2 = radius * radius;
- if (fx*fx + fy*fy > radius2)
- {
- /* If the focal point is outside the circle, let's move it
- to inside the circle. Per vg11 spec pg125 "If (fx, fy) lies outside ...
- For here, we set it at 0.9 ratio to the center.
- */
- vg_lite_float_t fr = (vg_lite_float_t)sqrt(fx*fx + fy*fy);
- fx = radius * fx / fr * 0.9f;
- fy = radius * fy / fr * 0.9f;
- focalX = grad->radial_grad.fx + fx;
- focalY = grad->radial_grad.fy + fy;
- }
- fxfy_2 = 2.0f * fx * fy;
- r2_fx2 = radius2 - fx * fx;
- r2_fy2 = radius2 - fy * fy;
- r2_fx2_2 = 2.0f * r2_fx2;
- r2_fy2_2 = 2.0f * r2_fy2;
- r2_fx2_fy2 = r2_fx2 - fy * fy;
- r2_fx2_fy2sq = r2_fx2_fy2 * r2_fx2_fy2;
- /* _____________________________________
- ** dx fx + dy fy + \/r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2
- ** g = -------------------------------------------------------
- ** r^2 - fx^2 - fy^2
- **
- ** Where
- **
- ** dx := F(x) - focalX
- ** dy := F(y) - focalY
- ** fx := focalX - centerX
- ** fy := focalX - centerY
- **
- ** and
- **
- ** F(x) := (x + 0.5) m00 + (y + 0.5) m01 + m02
- ** F(y) := (x + 0.5) m10 + (y + 0.5) m11 + m12
- **
- ** So, dx can be factored into
- **
- ** dx = (x + 0.5) m00 + (y + 0.5) m01 + m02 - focalX
- ** = x m00 + y m01 + 0.5 m00 + 0.5 m01 + m02 - focalX
- **
- ** = x m00 + y m01 + cx
- **
- ** where
- **
- ** cx := 0.5 m00 + 0.5 m01 + m02 - focalX
- **
- ** The same way we can factor dy into
- **
- ** dy = x m10 + y m11 + cy
- **
- ** where
- **
- ** cy := 0.5 m10 + 0.5 m11 + m12 - focalY.
- **
- ** Now we can rewrite g as
- ** ______________________________________
- ** dx fx + dy fy / r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2
- ** g = ----------------- + \ / -------------------------------------
- ** r^2 - fx^2 - fy^2 \/ (r^2 - fx^2 - fy^2)^2
- ** ____
- ** = gLin + \/gRad
- **
- ** where
- **
- ** dx fx + dy fy
- ** gLin := -----------------
- ** r^2 - fx^2 - fy^2
- **
- ** r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2
- ** gRad := -------------------------------------
- ** (r^2 - fx^2 - fy^2)^2
- */
- cx
- = 0.5f * ( MAT(&inverse_matrix, 0, 0) + MAT(&inverse_matrix, 0, 1) )
- + MAT(&inverse_matrix, 0, 2)
- - focalX;
- cy
- = 0.5f * ( MAT(&inverse_matrix, 1, 0) + MAT(&inverse_matrix, 1, 1) )
- + MAT(&inverse_matrix, 1, 2)
- - focalY;
- /*
- ** dx fx + dy fy
- ** gLin := -----------------
- ** r^2 - fx^2 - fy^2
- **
- ** We can factor the top half into
- **
- ** = (x m00 + y m01 + cx) fx + (x m10 + y m11 + cy) fy
- **
- ** = x (m00 fx + m10 fy)
- ** + y (m01 fx + m11 fy)
- ** + cx fx + cy fy.
- */
- rgStepXLin
- = ( MAT(&inverse_matrix, 0, 0) * fx + MAT(&inverse_matrix, 1, 0) * fy )
- / r2_fx2_fy2;
- rgStepYLin
- = ( MAT(&inverse_matrix, 0, 1) * fx + MAT(&inverse_matrix, 1, 1) * fy )
- / r2_fx2_fy2;
- rgConstantLin = ( cx * fx + cy * fy ) / r2_fx2_fy2;
- /*
- ** r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2
- ** gRad := -------------------------------------
- ** (r^2 - fx^2 - fy^2)^2
- **
- ** r^2 (dx^2 + dy^2) - dx^2 fy^2 - dy^2 fx^2 + 2 dx dy fx fy
- ** := ---------------------------------------------------------
- ** (r^2 - fx^2 - fy^2)^2
- **
- ** dx^2 (r^2 - fy^2) + dy^2 (r^2 - fx^2) + 2 dx dy fx fy
- ** := -----------------------------------------------------
- ** (r^2 - fx^2 - fy^2)^2
- **
- ** First, lets factor dx^2 into
- **
- ** dx^2 = (x m00 + y m01 + cx)^2
- ** = x^2 m00^2 + y^2 m01^2 + 2 x y m00 m01
- ** + 2 x m00 cx + 2 y m01 cx + cx^2
- **
- ** = x^2 (m00^2)
- ** + y^2 (m01^2)
- ** + x y (2 m00 m01)
- ** + x (2 m00 cx)
- ** + y (2 m01 cx)
- ** + cx^2.
- **
- ** The same can be done for dy^2:
- **
- ** dy^2 = x^2 (m10^2)
- ** + y^2 (m11^2)
- ** + x y (2 m10 m11)
- ** + x (2 m10 cy)
- ** + y (2 m11 cy)
- ** + cy^2.
- **
- ** Let's also factor dx dy into
- **
- ** dx dy = (x m00 + y m01 + cx) (x m10 + y m11 + cy)
- ** = x^2 m00 m10 + y^2 m01 m11 + x y m00 m11 + x y m01 m10
- ** + x m00 cy + x m10 cx + y m01 cy + y m11 cx + cx cy
- **
- ** = x^2 (m00 m10)
- ** + y^2 (m01 m11)
- ** + x y (m00 m11 + m01 m10)
- ** + x (m00 cy + m10 cx)
- ** + y (m01 cy + m11 cx)
- ** + cx cy.
- **
- ** Now that we have all this, lets look at the top of gRad.
- **
- ** = dx^2 (r^2 - fy^2) + dy^2 (r^2 - fx^2) + 2 dx dy fx fy
- ** = x^2 m00^2 (r^2 - fy^2) + y^2 m01^2 (r^2 - fy^2)
- ** + x y 2 m00 m01 (r^2 - fy^2) + x 2 m00 cx (r^2 - fy^2)
- ** + y 2 m01 cx (r^2 - fy^2) + cx^2 (r^2 - fy^2)
- ** + x^2 m10^2 (r^2 - fx^2) + y^2 m11^2 (r^2 - fx^2)
- ** + x y 2 m10 m11 (r^2 - fx^2) + x 2 m10 cy (r^2 - fx^2)
- ** + y 2 m11 cy (r^2 - fx^2) + cy^2 (r^2 - fx^2)
- ** + x^2 m00 m10 2 fx fy + y^2 m01 m11 2 fx fy
- ** + x y (m00 m11 + m01 m10) 2 fx fy
- ** + x (m00 cy + m10 cx) 2 fx fy + y (m01 cy + m11 cx) 2 fx fy
- ** + cx cy 2 fx fy
- **
- ** = x^2 ( m00^2 (r^2 - fy^2)
- ** + m10^2 (r^2 - fx^2)
- ** + m00 m10 2 fx fy
- ** )
- ** + y^2 ( m01^2 (r^2 - fy^2)
- ** + m11^2 (r^2 - fx^2)
- ** + m01 m11 2 fx fy
- ** )
- ** + x y ( 2 m00 m01 (r^2 - fy^2)
- ** + 2 m10 m11 (r^2 - fx^2)
- ** + (m00 m11 + m01 m10) 2 fx fy
- ** )
- ** + x ( 2 m00 cx (r^2 - fy^2)
- ** + 2 m10 cy (r^2 - fx^2)
- ** + (m00 cy + m10 cx) 2 fx fy
- ** )
- ** + y ( 2 m01 cx (r^2 - fy^2)
- ** + 2 m11 cy (r^2 - fx^2)
- ** + (m01 cy + m11 cx) 2 fx fy
- ** )
- ** + cx^2 (r^2 - fy^2) + cy^2 (r^2 - fx^2) + cx cy 2 fx fy.
- */
- rgStepXXRad =
- (
- MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 0, 0) * r2_fy2
- + MAT(&inverse_matrix, 1, 0) * MAT(&inverse_matrix, 1, 0) * r2_fx2
- + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 1, 0) * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgStepYYRad =
- (
- MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 0, 1) * r2_fy2
- + MAT(&inverse_matrix, 1, 1) * MAT(&inverse_matrix, 1, 1) * r2_fx2
- + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 1, 1) * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgStepXYRad =
- (
- MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 0, 1) * r2_fy2_2
- + MAT(&inverse_matrix, 1, 0) * MAT(&inverse_matrix, 1, 1) * r2_fx2_2
- + (
- MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 1, 1)
- + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 1, 0)
- )
- * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgStepXRad =
- (
- MAT(&inverse_matrix, 0, 0) * cx * r2_fy2_2
- + MAT(&inverse_matrix, 1, 0) * cy * r2_fx2_2
- + (
- MAT(&inverse_matrix, 0, 0) * cy
- + MAT(&inverse_matrix, 1, 0) * cx
- )
- * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgStepYRad =
- (
- MAT(&inverse_matrix, 0, 1) * cx * r2_fy2_2
- + MAT(&inverse_matrix, 1, 1) * cy * r2_fx2_2
- + (
- MAT(&inverse_matrix, 0, 1) * cy
- + MAT(&inverse_matrix, 1, 1) * cx
- )
- * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgConstantRad =
- (
- cx * cx * r2_fy2
- + cy * cy * r2_fx2
- + cx * cy * fxfy_2
- )
- / r2_fx2_fy2sq;
- /* Setup the command buffer. */
- data = &rgConstantLin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A04,*(uint32_t*) data));
- data = &rgStepXLin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A06,*(uint32_t*) data));
- data = &rgStepYLin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A08,*(uint32_t*) data));
- data = &rgConstantRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A05,*(uint32_t*) data));
- data = &rgStepXRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A07,*(uint32_t*) data));
- data = &rgStepYRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A09,*(uint32_t*) data));
- data = &rgStepXXRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A03,*(uint32_t*) data));
- data = &rgStepYYRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0A,*(uint32_t*) data));
- data = &rgStepXYRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0B,*(uint32_t*) data));
- VG_LITE_RETURN_ERROR(set_interpolation_steps(target, source->width, source->height, matrix));
- /* enable pre-multiplied in image unit */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) |
- filter_mode | rad_tile | conversion | src_premultiply_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, paint_color));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, tiled_source));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width));
- /* Work on path states. */
- matrix = path_matrix;
- if (ts_is_fullscreen == 0){
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix);
- point_min = point_max = temp;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- point_min.x = MAX(point_min.x, 0);
- point_min.y = MAX(point_min.y, 0);
- point_max.x = MIN(point_max.x, dst_align_width);
- point_max.y = MIN(point_max.y, target->height);
- if (s_context.scissor_set) {
- point_min.x = MAX(point_min.x, s_context.scissor[0]);
- point_min.y = MAX(point_min.y, s_context.scissor[1]);
- point_max.x = MIN(point_max.x, s_context.scissor[0] + s_context.scissor[2]);
- point_max.y = MIN(point_max.y, s_context.scissor[1] + s_context.scissor[3]);
- }
- }
- /* Convert states into hardware values. */
- blend_mode = convert_blend(blend);
- format = convert_path_format(path->format);
- quality = convert_path_quality(path->quality);
- tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0;
- fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0;
- tessellation_size = s_context.tessbuf.L2_size ? s_context.tessbuf.L2_size : s_context.tessbuf.L1_size;
- /* Setup the command buffer. */
- /* Program color register. */
- /* enable pre-multiplied from VG to VGPE */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, 0x02000002 | s_context.capabilities.cap.tiled | in_premult | imageMode | blend_mode | transparency_mode | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000400 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */
- /* Program matrix. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &matrix->m[0][0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &matrix->m[0][1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &matrix->m[0][2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &matrix->m[1][0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &matrix->m[1][1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &matrix->m[1][2]));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1)
- {
- if (path->path_changed != 0) {
- if (path->uploaded.handle != NULL) {
- free_memory.memory_handle = path->uploaded.handle;
- vg_lite_kernel(VG_LITE_FREE, &free_memory);
- path->uploaded.address = 0;
- path->uploaded.memory = NULL;
- path->uploaded.handle = NULL;
- }
- /* Allocate memory for the path data. */
- memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8);
- return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4;
- memory.contiguous = 1;
- VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory));
- ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0;
- ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8);
- ((uint32_t *) memory.memory)[1] = 0;
- memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length);
- ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN();
- ((uint32_t *) memory.memory)[return_offset + 1] = 0;
- path->uploaded.handle = memory.memory_handle;
- path->uploaded.memory = memory.memory;
- path->uploaded.address = memory.memory_gpu;
- path->uploaded.bytes = memory.bytes;
- path->path_changed = 0;
- }
- }
- /* Setup tessellation loop. */
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- for (y = point_min.y; y < point_max.y; y += height) {
- for (x = point_min.x; x < point_max.x; x += width) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 15));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- }
- }
- }
- }
- /* Setup tessellation loop. */
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- for (y = point_min.y; y < point_max.y; y += height) {
- for (x = point_min.x; x < point_max.x; x += width) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 15));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A01, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- if (VLM_PATH_STROKE_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->stroke->uploaded.address, path->stroke->uploaded.bytes));
- } else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- }
- }
- }
- /* Finialize command buffer. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0));
- return error;
- }
- #else /* (CHIPID==0x355 || CHIPID==0x255) */
- /* GC555 vg_lite_draw API implementation
- */
- vg_lite_error_t vg_lite_draw(vg_lite_buffer_t* target,
- vg_lite_path_t* path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t* matrix,
- vg_lite_blend_t blend,
- vg_lite_color_t color)
- {
- #if DUMP_API
- FUNC_DUMP(vg_lite_draw)(target, path, fill_rule, matrix, blend, color);
- #endif
- uint32_t blend_mode;
- uint32_t format, quality, tiling, fill;
- uint32_t tessellation_size;
- vg_lite_error_t error;
- vg_lite_point_t point_min = { 0 }, point_max = { 0 }, temp = { 0 };
- int width, height;
- uint8_t ts_is_fullscreen = 0;
- uint32_t return_offset = 0;
- vg_lite_kernel_free_t free_memory;
- vg_lite_kernel_allocate_t memory;
- float new_matrix[6];
- float scale, bias;
- uint32_t tile_setting = 0;
- uint32_t in_premult = 0;
- uint32_t premul_flag = 0;
- #if (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_512_PARALLEL_PATHS)
- uint32_t parallel_workpaths1 = 2;
- uint32_t parallel_workpaths2 = 2;
- #endif
- #if (!gcFEATURE_VG_SPLIT_PATH || !gcFEATURE_VG_PARALLEL_PATHS || !gcFEATURE_VG_512_PARALLEL_PATHS)
- int32_t y = 0;
- uint32_t par_height = 0;
- int32_t next_boundary = 0;
- #endif
- #if gcFEATURE_VG_TRACE_API
- VGLITE_LOG("vg_lite_draw %p %p %d %p %d 0x%08X\n", target, path, fill_rule, matrix, blend, color);
- VGLITE_LOG(" path_type %d, path_length %d, stroke_size %d\n", path->path_type, path->path_length, path->stroke_size);
- #endif
- #if gcFEATURE_VG_ERROR_CHECK
- #if !gcFEATURE_VG_QUALITY_8X
- if (path->quality == VG_LITE_UPPER) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_24BIT
- if (target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_NEW_BLEND_MODE
- if (blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- if (!path || !path->path) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- #endif /* gcFEATURE_VG_ERROR_CHECK */
- if (!path->path_length) {
- return VG_LITE_SUCCESS;
- }
- if (!matrix) {
- matrix = &identity_mtx;
- }
- #if gcFEATURE_VG_GAMMA
- set_gamma_dest_only(target, VGL_FALSE);
- #endif
- #if gcFEATURE_VG_GLOBAL_ALPHA
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff));
- }
- #endif
- /*blend input into context*/
- s_context.blend_mode = blend;
- /* Adjust premultiply setting according to openvg condition */
- target->apply_premult = 0;
- premul_flag = (s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE)
- ||(s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL);
- if (target->premultiplied == 0 && premul_flag == 0) {
- in_premult = 0x10000000;
- target->apply_premult = 1;
- }
- else if ((target->premultiplied == 1) ||
- (target->premultiplied == 0 && premul_flag == 1)) {
- in_premult = 0x00000000;
- }
- error = set_render_target(target);
- if (error != VG_LITE_SUCCESS) {
- return error;
- }
- if ((target->format == VG_LITE_YUYV || target->format == VG_LITE_YUY2 || target->format == VG_LITE_YUY2_TILED
- || target->format == VG_LITE_AYUY2 || target->format == VG_LITE_AYUY2_TILED)
- && path->quality != VG_LITE_LOW)
- {
- path->quality = VG_LITE_LOW;
- printf("If target is YUV group , the path qulity should use VG_LITE_LOW.\n");
- }
- width = target->width;
- height = target->height;
- if (s_context.scissor_set) {
- width = s_context.scissor[2] - s_context.scissor[0];
- height = s_context.scissor[3] - s_context.scissor[1];
- }
- if (width == 0 || height == 0)
- return VG_LITE_NO_CONTEXT;
- if ((target->width <= width) && (target->height <= height) && (!s_context.scissor_set))
- {
- ts_is_fullscreen = 1;
- point_min.x = 0;
- point_min.y = 0;
- point_max.x = target->width;
- point_max.y = target->height;
- }
- if (ts_is_fullscreen == 0) {
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix);
- point_min = point_max = temp;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- if (point_min.x < 0) point_min.x = 0;
- if (point_min.y < 0) point_min.y = 0;
- if (point_max.x > target->width) point_max.x = target->width;
- if (point_max.y > target->height) point_max.y = target->height;
- if (s_context.scissor_set) {
- point_min.x = MAX(point_min.x, s_context.scissor[0]);
- point_min.y = MAX(point_min.y, s_context.scissor[1]);
- point_max.x = MIN(point_max.x, s_context.scissor[2]);
- point_max.y = MIN(point_max.y, s_context.scissor[3]);
- }
- }
- width = point_max.x - point_min.x;
- height = point_max.y - point_min.y;
- scale = 1.0f;
- bias = 0.0f;
- new_matrix[0] = matrix->m[0][0] * scale;
- new_matrix[1] = matrix->m[0][1] * scale;
- new_matrix[2] = (matrix->m[0][0] + matrix->m[0][1]) * bias + matrix->m[0][2];
- new_matrix[3] = matrix->m[1][0] * scale;
- new_matrix[4] = matrix->m[1][1] * scale;
- new_matrix[5] = (matrix->m[1][0] + matrix->m[1][1]) * bias + matrix->m[1][2];
- /* Convert states into hardware values. */
- blend_mode = convert_blend(blend);
- format = convert_path_format(path->format);
- quality = convert_path_quality(path->quality);
- tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0;
- fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0;
- tessellation_size = s_context.tessbuf.tessbuf_size;
- #if gcFEATURE_VG_TESSELLATION_TILED_OUT
- tile_setting = (target->tiled != VG_LITE_LINEAR) ? 0x40 : 0;
- #endif
- /* Setup the command buffer. */
- /* Program color register. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, in_premult | s_context.capabilities.cap.tiled | blend_mode | tile_setting | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color));
- /* Program tessellation control: for TS module. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */
- /* Program matrix. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void*)&new_matrix[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void*)&new_matrix[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void*)&new_matrix[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void*)&new_matrix[3]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void*)&new_matrix[4]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void*)&new_matrix[5]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACD, (void*)&matrix->m[0][2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACE, (void*)&matrix->m[1][2]));
- /* DDRLess does not support uploading path data. */
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1)
- {
- if (path->path_changed != 0) {
- if (path->uploaded.handle != NULL) {
- free_memory.memory_handle = path->uploaded.handle;
- VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_FREE, &free_memory));
- path->uploaded.address = 0;
- path->uploaded.memory = NULL;
- path->uploaded.handle = NULL;
- }
- /* Allocate memory for the path data. */
- memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8);
- return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4;
- memory.contiguous = 1;
- VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory));
- ((uint64_t*)memory.memory)[(path->path_length + 7) / 8] = 0;
- ((uint32_t*)memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8);
- ((uint32_t*)memory.memory)[1] = 0;
- memcpy((uint8_t*)memory.memory + 8, path->path, path->path_length);
- ((uint32_t*)memory.memory)[return_offset] = VG_LITE_RETURN();
- ((uint32_t*)memory.memory)[return_offset + 1] = 0;
- path->uploaded.handle = memory.memory_handle;
- path->uploaded.memory = memory.memory;
- path->uploaded.address = memory.memory_gpu;
- path->uploaded.bytes = memory.bytes;
- path->path_changed = 0;
- }
- }
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- vglitemDUMP_BUFFER("path", (size_t)path->uploaded.address, (uint8_t*)(path->uploaded.memory), 0, path->uploaded.bytes);
- }
- #if !DUMP_COMMAND_CAPTURE
- vglitemDUMP("@[memory 0x%08X 0x%08X]", s_context.tessbuf.physical_addr, s_context.tessbuf.tessbuf_size);
- #endif
- if (width + point_min.x > target->width) {
- width = target->width - point_min.x;
- }
- #if (!gcFEATURE_VG_SPLIT_PATH || !gcFEATURE_VG_PARALLEL_PATHS || !gcFEATURE_VG_512_PARALLEL_PATHS)
- s_context.tessbuf.tess_w_h = width | (height << 16);
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- #if !gcFEATURE_VG_PARALLEL_PATHS
- if (height <= 128)
- parallel_workpaths1 = 4;
- else
- parallel_workpaths1 = height * 128 / 4096 - 1;
- if (parallel_workpaths1 > parallel_workpaths2)
- parallel_workpaths1 = parallel_workpaths2;
- #endif
- for (y = point_min.y; y < point_max.y; y += par_height) {
- #if !gcFEATURE_VG_512_PARALLEL_PATHS
- next_boundary = (y + 512) & 0xfffffe00;
- #elif (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_SPLIT_PATH)
- next_boundary = (y + 32) & 0xffffffe0;
- #else
- next_boundary = (y + 16) & 0xfffffff0;
- #endif
- par_height = ((next_boundary < point_max.y) ? next_boundary - y : (point_max.y - y));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, in_premult | s_context.capabilities.cap.tiled | blend_mode | tile_setting | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color));
- /* Program tessellation control: for TS module. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (par_height << 16)));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00000101));
- #if !gcFEATURE_VG_PARALLEL_PATHS
- s_context.path_counter++;
- if (parallel_workpaths1 == s_context.path_counter) {
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 7));
- s_context.path_counter = 0;
- }
- #endif
- }
- }
- }
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- #if !gcFEATURE_VG_PARALLEL_PATHS
- if (height <= 128)
- parallel_workpaths1 = 4;
- else
- parallel_workpaths1 = height * 128 / 4096 - 1;
- if (parallel_workpaths1 > parallel_workpaths2)
- parallel_workpaths1 = parallel_workpaths2;
- #endif
- for (y = point_min.y; y < point_max.y; y += par_height) {
- #if !gcFEATURE_VG_512_PARALLEL_PATHS
- next_boundary = (y + 512) & 0xfffffe00;
- #elif (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_SPLIT_PATH)
- next_boundary = (y + 32) & 0xffffffe0;
- #else
- next_boundary = (y + 16) & 0xfffffff0;
- #endif
- par_height = ((next_boundary < point_max.y) ? next_boundary - y : (point_max.y - y));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, in_premult | s_context.capabilities.cap.tiled | blend_mode | tile_setting | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (par_height << 16)));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00000101));
- #if !gcFEATURE_VG_PARALLEL_PATHS
- s_context.path_counter++;
- if (parallel_workpaths1 == s_context.path_counter) {
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 7));
- s_context.path_counter = 0;
- }
- #endif
- }
- }
- }
- #else
- {
- s_context.tessbuf.tess_w_h = width | (height << 16);
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- }
- }
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- /* Tessellate path. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- }
- }
- #endif
- #if gcFEATURE_VG_GLOBAL_ALPHA
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF));
- }
- #endif
- return error;
- }
- /* GC555 vg_lite_draw_pattern API implementation
- */
- vg_lite_error_t vg_lite_draw_pattern(vg_lite_buffer_t *target,
- vg_lite_path_t *path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t *path_matrix,
- vg_lite_buffer_t *source,
- vg_lite_matrix_t *pattern_matrix,
- vg_lite_blend_t blend,
- vg_lite_pattern_mode_t pattern_mode,
- vg_lite_color_t pattern_color,
- vg_lite_color_t color,
- vg_lite_filter_t filter)
- {
- #if DUMP_API
- FUNC_DUMP(vg_lite_draw_pattern)(target, path, fill_rule, path_matrix, source, pattern_matrix, blend, pattern_mode, pattern_color, color, filter);
- #endif
- #if gcFEATURE_VG_IM_INPUT
- vg_lite_error_t error = VG_LITE_SUCCESS;
- vg_lite_matrix_t inverse_matrix;
- vg_lite_float_t x_step[3];
- vg_lite_float_t y_step[3];
- vg_lite_float_t c_step[3];
- uint32_t imageMode = 0;
- uint32_t blend_mode;
- uint32_t filter_mode = 0;
- int32_t stride;
- uint32_t conversion = 0;
- uint32_t tiled_source;
- vg_lite_matrix_t matrix;
- uint32_t pattern_tile = 0;
- uint32_t transparency_mode = 0;
- uint32_t tile_setting = 0;
- uint32_t yuv2rgb = 0;
- uint32_t uv_swiz = 0;
- /* The following code is from "draw path" */
- uint32_t format, quality, tiling, fill;
- uint32_t tessellation_size;
- vg_lite_kernel_allocate_t memory;
- vg_lite_kernel_free_t free_memory;
- uint32_t return_offset = 0;
- vg_lite_point_t point_min = { 0 }, point_max = { 0 }, temp = { 0 };
- int width, height;
- uint8_t ts_is_fullscreen = 0;
- float new_matrix[6];
- float Scale, Bias;
- uint32_t compress_mode;
- uint32_t src_premultiply_enable = 0;
- uint32_t index_endian = 0;
- uint32_t in_premult = 0;
- uint32_t paintType = 0;
- uint32_t premul_flag = 0;
- uint32_t prediv_flag = 0;
- uint8_t lvgl_sw_blend = 0;
- #if (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_512_PARALLEL_PATHS)
- uint32_t parallel_workpaths1 = 2;
- uint32_t parallel_workpaths2 = 2;
- #endif
- #if (!gcFEATURE_VG_SPLIT_PATH || !gcFEATURE_VG_PARALLEL_PATHS || !gcFEATURE_VG_512_PARALLEL_PATHS)
- int32_t y = 0;
- uint32_t par_height = 0;
- int32_t next_boundary = 0;
- #endif
- #if gcFEATURE_VG_TRACE_API
- VGLITE_LOG("vg_lite_draw_pattern %p %p %d %p %p %p %d %d 0x%08X %d\n",
- target, path, fill_rule, path_matrix, source, pattern_matrix, blend, pattern_mode, pattern_color, filter);
- #endif
- #if gcFEATURE_VG_ERROR_CHECK
- #if !gcFEATURE_VG_QUALITY_8X
- if (path->quality == VG_LITE_UPPER) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_INDEX_ENDIAN
- if ((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_RGBA8_ETC2_EAC
- if (source->format == VG_LITE_RGBA8888_ETC2_EAC) {
- return VG_LITE_NOT_SUPPORT;
- }
- #else
- if ((source->format == VG_LITE_RGBA8888_ETC2_EAC) && (source->width % 16 || source->height % 4)) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- #endif
- #if !gcFEATURE_VG_YUY2_INPUT
- if (source->format == VG_LITE_YUYV || source->format == VG_LITE_YUY2) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_YUV_INPUT
- if ((source->format >= VG_LITE_NV12 && source->format <= VG_LITE_NV16) || source->format == VG_LITE_NV24) {
- return VG_LITE_NOT_SUPPORT;
- }
- #elif !gcFEATURE_VG_NV24_INPUT
- if (source->format == VG_LITE_NV24) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_AYUV_INPUT
- if (source->format == VG_LITE_ANV12 || source->format == VG_LITE_AYUY2) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_YUV_TILED_INPUT
- if ((source->format >= VG_LITE_YUY2_TILED && source->format <= VG_LITE_AYUY2_TILED) || (source->format == VG_LITE_NV24_TILED)) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_24BIT
- if ((target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) ||
- (source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658)) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_24BIT_PLANAR
- if (source->format >= VG_LITE_ABGR8565_PLANAR && source->format <= VG_LITE_RGBA5658_PLANAR) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_STENCIL
- if (source->image_mode == VG_LITE_STENCIL_MODE) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_NEW_BLEND_MODE
- if (blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- if (!path || !path->path) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- VG_LITE_RETURN_ERROR(srcbuf_align_check(source));
- VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, source->height));
- #endif /* gcFEATURE_VG_ERROR_CHECK */
- #if !gcFEATURE_VG_LVGL_SUPPORT
- if ((blend >= VG_LITE_BLEND_ADDITIVE_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) || (blend == VG_LITE_BLEND_NORMAL_LVGL && gcFEATURE_VG_SRC_PREMULTIPLIED)) {
- if (!source->lvgl_buffer) {
- source->lvgl_buffer = (vg_lite_buffer_t *)vg_lite_os_malloc(sizeof(vg_lite_buffer_t));
- *source->lvgl_buffer = *source;
- source->lvgl_buffer->lvgl_buffer = NULL;
- vg_lite_allocate(source->lvgl_buffer);
- }
- /* Make sure render target is up to date before reading RT. */
- vg_lite_finish();
- setup_lvgl_image(target, source, source->lvgl_buffer, blend);
- blend = VG_LITE_BLEND_SRC_OVER;
- lvgl_sw_blend = 1;
- }
- #endif
- if (!path->path_length) {
- return VG_LITE_SUCCESS;
- }
- if (!path_matrix) {
- path_matrix = &identity_mtx;
- }
- if (!pattern_matrix) {
- pattern_matrix = &identity_mtx;
- }
- /* Work on pattern states. */
- matrix = *pattern_matrix;
- if (source->paintType == VG_LITE_PAINT_PATTERN)
- {
- matrix.m[2][0] = 0;
- matrix.m[2][1] = 0;
- matrix.m[2][2] = 1;
- source->image_mode = VG_LITE_NONE_IMAGE_MODE;
- }
- #if gcFEATURE_VG_INDEX_ENDIAN
- if ((source->format >= VG_LITE_INDEX_1) && (source->format <= VG_LITE_INDEX_4) && source->index_endian) {
- index_endian = 1 << 14;
- }
- #endif
- #if gcFEATURE_VG_GAMMA
- save_st_gamma_src_dest(source, target);
- #endif
- #if gcFEATURE_VG_GLOBAL_ALPHA
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff));
- }
- #endif
- /*blend input into context*/
- s_context.blend_mode = blend;
- in_premult = 0x00000000;
- /* Adjust premultiply setting according to openvg condition */
- src_premultiply_enable = 0x01000100;
- if (s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 &&
- (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) {
- prediv_flag = 0;
- }
- else {
- prediv_flag = 1;
- }
- if ((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || source->image_mode == VG_LITE_STENCIL_MODE
- || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL)) {
- premul_flag = 1;
- }
- else {
- premul_flag = 0;
- }
- if ((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x10000000;
- }
- /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */
- else if (source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 0 && target->premultiplied == 1) ||
- (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- if ((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && blend <= VG_LITE_BLEND_SUBTRACT) {
- in_premult = 0x00000000;
- }
- if (source->premultiplied == target->premultiplied && premul_flag == 0) {
- target->apply_premult = 1;
- }
- else {
- target->apply_premult = 0;
- }
- #if (gcFEATURE_VG_SRC_PREMULTIPLIED == 0)
- if (blend == VG_LITE_BLEND_NORMAL_LVGL)
- in_premult = 0x00000000;
- #endif
- error = set_render_target(target);
- if (error != VG_LITE_SUCCESS) {
- return error;
- }
- if ((target->format == VG_LITE_YUYV || target->format == VG_LITE_YUY2 || target->format == VG_LITE_YUY2_TILED
- || target->format == VG_LITE_AYUY2 || target->format == VG_LITE_AYUY2_TILED)
- && path->quality != VG_LITE_LOW)
- {
- path->quality = VG_LITE_LOW;
- printf("If target is YUV group , the path qulity should use VG_LITE_LOW.\n");
- }
- transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000:0);
- width = target->width;
- height = target->height;
- if (s_context.scissor_set) {
- width = s_context.scissor[2] - s_context.scissor[0];
- height = s_context.scissor[3] - s_context.scissor[1];
- }
- if (width == 0 || height == 0)
- return VG_LITE_NO_CONTEXT;
- if ((target->width <= width) && (target->height <= height) && (!s_context.scissor_set))
- {
- ts_is_fullscreen = 1;
- point_min.x = 0;
- point_min.y = 0;
- point_max.x = target->width;
- point_max.y = target->height;
- }
- /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */
- if ((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) {
- conversion = 0x80000000;
- }
- /* Compute inverse matrix. */
- if (!inverse(&inverse_matrix, &matrix))
- return VG_LITE_INVALID_ARGUMENT;
- #if gcFEATURE_VG_MATH_PRECISION_FIX
- /* Compute interpolation steps. */
- x_step[0] = inverse_matrix.m[0][0];
- x_step[1] = inverse_matrix.m[1][0];
- x_step[2] = inverse_matrix.m[2][0];
- y_step[0] = inverse_matrix.m[0][1];
- y_step[1] = inverse_matrix.m[1][1];
- y_step[2] = inverse_matrix.m[2][1];
- c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]);
- c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]);
- c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2];
- #else
- /* Compute interpolation steps. */
- x_step[0] = inverse_matrix.m[0][0] / source->width;
- x_step[1] = inverse_matrix.m[1][0] / source->height;
- x_step[2] = inverse_matrix.m[2][0];
- y_step[0] = inverse_matrix.m[0][1] / source->width;
- y_step[1] = inverse_matrix.m[1][1] / source->height;
- y_step[2] = inverse_matrix.m[2][1];
- c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source->width;
- c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source->height;
- c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2];
- #endif
- /* Determine image mode (NORMAL, NONE , MULTIPLY or STENCIL) depending on the color. */
- switch (source->image_mode) {
- case VG_LITE_NONE_IMAGE_MODE:
- imageMode = 0x0;
- break;
- case VG_LITE_MULTIPLY_IMAGE_MODE:
- imageMode = 0x00002000;
- break;
- case VG_LITE_NORMAL_IMAGE_MODE:
- case VG_LITE_ZERO:
- imageMode = 0x00001000;
- break;
- case VG_LITE_STENCIL_MODE:
- imageMode = 0x00003000;
- break;
- case VG_LITE_RECOLOR_MODE:
- imageMode = 0x00006000;
- break;
- }
- switch (filter) {
- case VG_LITE_FILTER_POINT:
- filter_mode = 0;
- break;
- case VG_LITE_FILTER_LINEAR:
- filter_mode = 0x10000;
- break;
- case VG_LITE_FILTER_BI_LINEAR:
- filter_mode = 0x20000;
- break;
- case VG_LITE_FILTER_GAUSSIAN:
- filter_mode = 0x30000;
- break;
- }
- tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ;
- compress_mode = (uint32_t)source->compress_mode << 25;
- if (pattern_mode == VG_LITE_PATTERN_COLOR)
- {
- uint8_t a,r,g,b;
- pattern_tile = 0;
- a = pattern_color >> 24;
- r = pattern_color >> 16;
- g = pattern_color >> 8;
- b = pattern_color;
- pattern_color = (a << 24) | (b << 16) | (g << 8) | r;
- }
- else if (pattern_mode == VG_LITE_PATTERN_PAD)
- {
- pattern_tile = 0x1000;
- }
- #if gcFEATURE_VG_IM_REPEAT_REFLECT
- else if (pattern_mode == VG_LITE_PATTERN_REPEAT)
- {
- pattern_tile = 0x2000;
- }
- else if (pattern_mode == VG_LITE_PATTERN_REFLECT)
- {
- pattern_tile = 0x3000;
- }
- #endif
- else
- {
- return VG_LITE_INVALID_ARGUMENT;
- }
- if (source->paintType == VG_LITE_PAINT_PATTERN)
- {
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A04, (void *) &c_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A05, (void *) &c_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A06, (void *) &x_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A07, (void *) &x_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A08, (void *) &y_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A09, (void *) &y_step[1]));
- }
-
- /* Setup the command buffer. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[2]));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[2]));
- if (((source->format >= VG_LITE_YUY2) &&
- (source->format <= VG_LITE_AYUY2)) ||
- ((source->format >= VG_LITE_YUY2_TILED) &&
- (source->format <= VG_LITE_AYUY2_TILED))) {
- yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb);
- uv_swiz = convert_uv_swizzle(source->yuv.swizzle);
- }
- blend_mode = convert_blend(blend);
- if (source->paintType == VG_LITE_PAINT_PATTERN)
- {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) | filter_mode | pattern_tile | uv_swiz | yuv2rgb | conversion | compress_mode | src_premultiply_enable | index_endian));
- if (source->yuv.uv_planar) {
- /* Program u plane address if necessary. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A50, source->yuv.uv_planar));
- }
- if (source->yuv.v_planar) {
- /* Program v plane address if necessary. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A52, source->yuv.v_planar));
- }
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, pattern_color));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address));
- /* 24bit format stride configured to 4bpp. */
- if (source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658) {
- stride = source->stride / 3 * 4;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, stride | tiled_source));
- }
- else {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, source->stride | tiled_source));
- }
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width | (source->height << 16)));
- }
- else
- {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A25, convert_source_format(source->format) | filter_mode | pattern_tile | uv_swiz | yuv2rgb | conversion | compress_mode | src_premultiply_enable | index_endian));
- if (source->yuv.uv_planar) {
- /* Program u plane address if necessary. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar));
- }
- if (source->yuv.v_planar) {
- /* Program v plane address if necessary. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar));
- }
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A27, pattern_color));
- #if !gcFEATURE_VG_LVGL_SUPPORT
- if (lvgl_sw_blend) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->lvgl_buffer->address));
- }
- else
- #endif
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A29, source->address));
- /* 24bit format stride configured to 4bpp. */
- if (source->format >= VG_LITE_RGB888 && source->format <= VG_LITE_RGBA5658) {
- stride = source->stride / 3 * 4;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, stride | tiled_source));
- }
- else {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2B, source->stride | tiled_source));
- }
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2D, 0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2F, source->width | (source->height << 16)));
- }
- /* Work on path states. */
- matrix = *path_matrix;
- if (ts_is_fullscreen == 0) {
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], &matrix);
- point_min = point_max = temp;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], &matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], &matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
-
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], &matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
-
- point_min.x = MAX(point_min.x, 0);
- point_min.y = MAX(point_min.y, 0);
- point_max.x = MIN(point_max.x, target->width);
- point_max.y = MIN(point_max.y, target->height);
- if (s_context.scissor_set) {
- point_min.x = MAX(point_min.x, s_context.scissor[0]);
- point_min.y = MAX(point_min.y, s_context.scissor[1]);
- point_max.x = MIN(point_max.x, s_context.scissor[2]);
- point_max.y = MIN(point_max.y, s_context.scissor[3]);
- }
- }
- width = point_max.x - point_min.x;
- height = point_max.y - point_min.y;
- Scale = 1.0f;
- Bias = 0.0f;
- new_matrix[0] = matrix.m[0][0] * Scale;
- new_matrix[1] = matrix.m[0][1] * Scale;
- new_matrix[2] = (matrix.m[0][0] + matrix.m[0][1]) * Bias + matrix.m[0][2];
- new_matrix[3] = matrix.m[1][0] * Scale;
- new_matrix[4] = matrix.m[1][1] * Scale;
- new_matrix[5] = (matrix.m[1][0] + matrix.m[1][1]) * Bias + matrix.m[1][2];
- /* Convert states into hardware values. */
- format = convert_path_format(path->format);
- quality = convert_path_quality(path->quality);
- tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0;
- fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0;
- tessellation_size = s_context.tessbuf.tessbuf_size;
- #if gcFEATURE_VG_TESSELLATION_TILED_OUT
- tile_setting = (target->tiled != VG_LITE_LINEAR) ? 0x40 : 0;
- #endif
- if (source->paintType == VG_LITE_PAINT_PATTERN) {
- paintType = 1 << 24 | 1 << 25;
- }
- /* Setup the command buffer. */
- #if gcFEATURE_VG_GLOBAL_ALPHA
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0AD1, s_context.dst_alpha_mode | s_context.dst_alpha_value | s_context.src_alpha_mode | s_context.src_alpha_value));
- #endif
- /* Program color register. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, in_premult | paintType |s_context.capabilities.cap.tiled | imageMode | blend_mode | transparency_mode | tile_setting | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable | 0x2));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color));
- /* Program matrix. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &new_matrix[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &new_matrix[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &new_matrix[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &new_matrix[3]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &new_matrix[4]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &new_matrix[5]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACD, (void *) &matrix.m[0][2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACE, (void *) &matrix.m[1][2]));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1)
- {
- if (path->path_changed != 0) {
- if (path->uploaded.handle != NULL) {
- free_memory.memory_handle = path->uploaded.handle;
- vg_lite_kernel(VG_LITE_FREE, &free_memory);
- path->uploaded.address = 0;
- path->uploaded.memory = NULL;
- path->uploaded.handle = NULL;
- }
- /* Allocate memory for the path data. */
- memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8);
- return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4;
- memory.contiguous = 1;
- VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory));
- ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0;
- ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8);
- ((uint32_t *) memory.memory)[1] = 0;
- memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length);
- ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN();
- ((uint32_t *) memory.memory)[return_offset + 1] = 0;
- path->uploaded.handle = memory.memory_handle;
- path->uploaded.memory = memory.memory;
- path->uploaded.address = memory.memory_gpu;
- path->uploaded.bytes = memory.bytes;
- path->path_changed = 0;
- }
- }
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- vglitemDUMP_BUFFER("path", (size_t)path->uploaded.address, (uint8_t *)(path->uploaded.memory), 0, path->uploaded.bytes);
- }
- #if !DUMP_COMMAND_CAPTURE
- vglitemDUMP("@[memory 0x%08X 0x%08X]", s_context.tessbuf.physical_addr, s_context.tessbuf.tessbuf_size);
- #endif
- if (width + point_min.x > target->width) {
- width = target->width - point_min.x;
- }
- #if (!gcFEATURE_VG_SPLIT_PATH || !gcFEATURE_VG_PARALLEL_PATHS || !gcFEATURE_VG_512_PARALLEL_PATHS)
- s_context.tessbuf.tess_w_h = width | (height << 16);
- #if !gcFEATURE_VG_PARALLEL_PATHS
- if (height <= 128)
- parallel_workpaths1 = 4;
- else
- parallel_workpaths1 = height * 128 / 4096 - 1;
- if (parallel_workpaths1 > parallel_workpaths2)
- parallel_workpaths1 = parallel_workpaths2;
- #endif
- for (y = point_min.y; y < point_max.y; y += par_height) {
- #if !gcFEATURE_VG_512_PARALLEL_PATHS
- next_boundary = (y + 512) & 0xfffffe00;
- #elif (!gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_SPLIT_PATH)
- next_boundary = (y + 32) & 0xffffffe0;
- #else
- next_boundary = (y + 16) & 0xfffffff0;
- #endif
- par_height = ((next_boundary < point_max.y) ? next_boundary - y : (point_max.y - y));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, in_premult | paintType | s_context.capabilities.cap.tiled | imageMode | blend_mode | transparency_mode | tile_setting | s_context.enable_mask | s_context.scissor_enable | s_context.color_transform | s_context.matrix_enable | 0x2));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, color));;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (par_height << 16)));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO)
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- #if !gcFEATURE_VG_PARALLEL_PATHS
- s_context.path_counter++;
- if (parallel_workpaths1 == s_context.path_counter) {
- VG_LITE_RETURN_ERROR(push_stall(&s_context, 7));
- s_context.path_counter = 0;
- }
- #endif
- }
- }
- #else
- {
- /* Tessellate path. */
- s_context.tessbuf.tess_w_h = width | (height << 16);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- }
- else {
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO)
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- }
- }
- #endif
- #if gcFEATURE_VG_GLOBAL_ALPHA
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF));
- }
- #endif
- vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride)*(source->height));
- #if DUMP_IMAGE
- dump_img(source->memory, source->width, source->height, source->format);
- #endif
- return error;
- #else
- return VG_LITE_NOT_SUPPORT;
- #endif
- }
- /* GC555 vg_lite_draw_linear_grad API implementation
- */
- vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t* target,
- vg_lite_path_t* path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t* path_matrix,
- vg_lite_ext_linear_gradient_t* grad,
- vg_lite_color_t paint_color,
- vg_lite_blend_t blend,
- vg_lite_filter_t filter)
- {
- #if DUMP_API
- FUNC_DUMP(vg_lite_draw_linear_grad)(target, path, fill_rule, path_matrix, grad, paint_color, blend, filter);
- #endif
- #if gcFEATURE_VG_LINEAR_GRADIENT_EXT && gcFEATURE_VG_IM_INPUT
- vg_lite_error_t error = VG_LITE_SUCCESS;
- uint32_t image_mode = 0;
- uint32_t blend_mode;
- uint32_t filter_mode = 0;
- uint32_t conversion = 0;
- uint32_t tiled_source;
- vg_lite_matrix_t inverse_matrix;
- vg_lite_float_t x_step[3];
- vg_lite_float_t y_step[3];
- vg_lite_float_t c_step[3];
- vg_lite_buffer_t* source = &grad->image;
- vg_lite_matrix_t* matrix = &grad->matrix;
- uint32_t linear_tile = 0;
- uint32_t transparency_mode = 0;
- uint32_t yuv2rgb = 0;
- uint32_t uv_swiz = 0;
- uint32_t in_premult = 0;
- uint32_t src_premultiply_enable = 0;
- uint32_t premul_flag = 0;
- uint32_t prediv_flag = 0;
- void* data;
- /* The following code is from "draw path" */
- uint32_t format, quality, tiling, fill;
- uint32_t tessellation_size;
- vg_lite_kernel_allocate_t memory;
- vg_lite_kernel_free_t free_memory;
- uint32_t return_offset = 0;
- vg_lite_point_t point_min = { 0 }, point_max = { 0 }, temp = { 0 };
- int width, height;
- uint8_t ts_is_fullscreen = 0;
- float new_matrix[6];
- float Scale, Bias;
- vg_lite_float_t dx, dy, dxdx_dydy;
- vg_lite_float_t lg_step_x_lin, lg_step_y_lin, lg_constant_lin;
- #if !gcFEATURE_VG_PARALLEL_PATHS
- uint32_t parallel_workpaths1 = 2;
- uint32_t parallel_workpaths2 = 2;
- #endif
- int y;
- int temp_height = 0;
- #if gcFEATURE_VG_TRACE_API
- VGLITE_LOG("vg_lite_draw_linear_grad %p %p %d %p %p 0x%08X %d %d\n",
- target, path, fill_rule, path_matrix, grad, paint_color, blend, filter);
- #endif
- #if gcFEATURE_VG_ERROR_CHECK
- #if !gcFEATURE_VG_QUALITY_8X
- if (path->quality == VG_LITE_UPPER) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_LVGL_SUPPORT
- if ((blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL)) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_24BIT
- if (target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_STENCIL
- if (source->image_mode == VG_LITE_STENCIL_MODE) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_NEW_BLEND_MODE
- if (blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_IM_REPEAT_REFLECT
- if (grad->spread_mode == VG_LITE_GRADIENT_SPREAD_REPEAT || grad->spread_mode == VG_LITE_GRADIENT_SPREAD_REFLECT) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- if (source->format == VG_LITE_A4 || source->format == VG_LITE_A8) {
- return VG_LITE_NOT_SUPPORT;
- }
- if (!path || !path->path) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- #endif /* gcFEATURE_VG_ERROR_CHECK */
- if (!path->path_length) {
- return VG_LITE_SUCCESS;
- }
- if (!path_matrix) {
- path_matrix = &identity_mtx;
- }
- #if gcFEATURE_VG_GAMMA
- set_gamma_dest_only(target, VGL_TRUE);
- #endif
- #if gcFEATURE_VG_GLOBAL_ALPHA
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff));
- }
- #endif
- /*blend input into context*/
- s_context.blend_mode = blend;
- src_premultiply_enable = 0x01000100;
- if (s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 &&
- (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) {
- prediv_flag = 0;
- }
- else {
- prediv_flag = 1;
- }
- if ((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || source->image_mode == VG_LITE_STENCIL_MODE
- || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL)) {
- premul_flag = 1;
- }
- else {
- premul_flag = 0;
- }
- if ((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x10000000;
- }
- /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */
- else if (source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 0 && target->premultiplied == 1) ||
- (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- if ((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && blend <= VG_LITE_BLEND_SUBTRACT) {
- #if (CHIPID==0x255)
- src_premultiply_enable = 0x00000000;
- #endif
- in_premult = 0x00000000;
- }
- if (source->premultiplied == target->premultiplied && premul_flag == 0) {
- target->apply_premult = 1;
- }
- else {
- target->apply_premult = 0;
- }
- error = set_render_target(target);
- if (error != VG_LITE_SUCCESS) {
- return error;
- } else if (error == VG_LITE_NO_CONTEXT) {
- /* If scissoring is enabled and no valid scissoring rectangles
- are present, no drawing occurs */
- return VG_LITE_SUCCESS;
- }
- transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000:0);
- width = s_context.tessbuf.tess_w_h & 0xFFFF;
- height = s_context.tessbuf.tess_w_h >> 16;
- if (width == 0 || height == 0)
- return VG_LITE_NO_CONTEXT;
- if ((target->width <= width) && (target->height <= height) && (!s_context.scissor_set))
- {
- ts_is_fullscreen = 1;
- point_min.x = 0;
- point_min.y = 0;
- point_max.x = target->width;
- point_max.y = target->height;
- }
- /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */
- if ((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) {
- conversion = 0x80000000;
- }
- /* Determine image mode (NORMAL, NONE , MULTIPLY or STENCIL) depending on the color. */
- switch (source->image_mode) {
- case VG_LITE_NONE_IMAGE_MODE:
- image_mode = 0x0;
- break;
- case VG_LITE_MULTIPLY_IMAGE_MODE:
- return VG_LITE_INVALID_ARGUMENT;
- case VG_LITE_NORMAL_IMAGE_MODE:
- case VG_LITE_ZERO:
- image_mode = 0x00001000;
- break;
- case VG_LITE_STENCIL_MODE:
- image_mode = 0x00003000;
- break;
- case VG_LITE_RECOLOR_MODE:
- image_mode = 0x00006000;
- break;
- }
- tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ;
- switch (grad->spread_mode) {
- case VG_LITE_GRADIENT_SPREAD_FILL:
- linear_tile = 0x0;
- break;
- case VG_LITE_GRADIENT_SPREAD_PAD:
- linear_tile = 0x1000;
- break;
- case VG_LITE_GRADIENT_SPREAD_REPEAT:
- linear_tile = 0x2000;
- break;
- case VG_LITE_GRADIENT_SPREAD_REFLECT:
- linear_tile = 0x3000;
- break;
- }
- switch (filter) {
- case VG_LITE_FILTER_POINT:
- filter_mode = 0;
- break;
- case VG_LITE_FILTER_LINEAR:
- filter_mode = 0x10000;
- break;
- case VG_LITE_FILTER_BI_LINEAR:
- filter_mode = 0x20000;
- break;
- case VG_LITE_FILTER_GAUSSIAN:
- filter_mode = 0x30000;
- break;
- }
- if (grad->spread_mode == VG_LITE_GRADIENT_SPREAD_FILL)
- {
- uint8_t a,r,g,b;
- a = paint_color >> 24;
- r = paint_color >> 16;
- g = paint_color >> 8;
- b = paint_color;
- paint_color = (a << 24) | (b << 16) | (g << 8) | r;
- }
- /* compute linear gradient paremeters */
- /* Compute inverse matrix. */
- if (!inverse(&inverse_matrix, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- dx = grad->linear_grad.X1 - grad->linear_grad.X0;
- dy = grad->linear_grad.Y1 - grad->linear_grad.Y0;
- #if gcFEATURE_VG_MATH_PRECISION_FIX
- dxdx_dydy = (vg_lite_float_t)((dx * dx + dy * dy) / sqrt((dx + 1) * (dx + 1) + (dy + 1) * (dy + 1)));
- #else
- dxdx_dydy = dx * dx + dy * dy;
- #endif
- /*
- ** dx (T(x) - x0) + dy (T(y) - y0)
- ** g = -------------------------------
- ** dx^2 + dy^2
- **
- ** where
- **
- ** dx := x1 - x0
- ** dy := y1 - y0
- ** T(x) := (x + 0.5) m00 + (y + 0.5) m01 + m02
- ** = x m00 + y m01 + 0.5 (m00 + m01) + m02
- ** T(y) := (x + 0.5) m10 + (y + 0.5) m11 + m12
- ** = x m10 + y m11 + 0.5 (m10 + m11) + m12.
- **
- ** We can factor the top line into:
- **
- ** = dx (x m00 + y m01 + 0.5 (m00 + m01) + m02 - x0)
- ** + dy (x m10 + y m11 + 0.5 (m10 + m11) + m12 - y0)
- **
- ** = x (dx m00 + dy m10)
- ** + y (dx m01 + dy m11)
- ** + dx (0.5 (m00 + m01) + m02 - x0)
- ** + dy (0.5 (m10 + m11) + m12 - y0).
- */
- lg_step_x_lin
- = (dx * MAT(&inverse_matrix, 0, 0) + dy * MAT(&inverse_matrix, 1, 0))
- / dxdx_dydy;
- lg_step_y_lin
- = (dx * MAT(&inverse_matrix, 0, 1) + dy * MAT(&inverse_matrix, 1, 1))
- / dxdx_dydy;
- lg_constant_lin =
- (
- (
- 0.5f * ( MAT(&inverse_matrix, 0, 0) + MAT(&inverse_matrix, 0, 1) )
- + MAT(&inverse_matrix, 0, 2) - grad->linear_grad.X0
- ) * dx
- +
- (
- 0.5f * ( MAT(&inverse_matrix, 1, 0) + MAT(&inverse_matrix, 1, 1) )
- + MAT(&inverse_matrix, 1, 2) - grad->linear_grad.Y0
- ) * dy
- )
- / dxdx_dydy;
- /* Setup the command buffer. */
- /* linear gradient parameters*/
- data = &lg_constant_lin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A04,*(uint32_t*) data));
- data = &lg_step_x_lin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A06,*(uint32_t*) data));
- data = &lg_step_y_lin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A08,*(uint32_t*) data));
- /* Compute inverse matrix. */
- if (!inverse(&inverse_matrix, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- #if gcFEATURE_VG_MATH_PRECISION_FIX
- /* Compute interpolation steps. */
- x_step[0] = inverse_matrix.m[0][0];
- x_step[1] = inverse_matrix.m[1][0];
- x_step[2] = inverse_matrix.m[2][0];
- y_step[0] = inverse_matrix.m[0][1];
- y_step[1] = inverse_matrix.m[1][1];
- y_step[2] = inverse_matrix.m[2][1];
- c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]);
- c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]);
- c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2];
- #else
- /* Compute interpolation steps. */
- x_step[0] = inverse_matrix.m[0][0] / source->width;
- x_step[1] = inverse_matrix.m[1][0] / source->height;
- x_step[2] = inverse_matrix.m[2][0];
- y_step[0] = inverse_matrix.m[0][1] / source->width;
- y_step[1] = inverse_matrix.m[1][1] / source->height;
- y_step[2] = inverse_matrix.m[2][1];
- c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source->width;
- c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source->height;
- c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2];
- #endif
- /* Setup the command buffer. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[2]));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[2]));
- if (((source->format >= VG_LITE_YUY2) &&
- (source->format <= VG_LITE_AYUY2)) ||
- ((source->format >= VG_LITE_YUY2_TILED) &&
- (source->format <= VG_LITE_AYUY2_TILED))) {
- yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb);
- uv_swiz = convert_uv_swizzle(source->yuv.swizzle);
- }
- if (source->yuv.uv_planar) {
- /* Program u plane address if necessary. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar));
- }
- if (source->yuv.v_planar) {
- /* Program v plane address if necessary. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar));
- }
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) |
- filter_mode | uv_swiz | yuv2rgb | linear_tile | conversion | src_premultiply_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, paint_color));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, tiled_source));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width | (source->height << 16)));
- /* Work on path states. */
- matrix = path_matrix;
- if (ts_is_fullscreen == 0) {
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix);
- point_min = point_max = temp;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- point_min.x = MAX(point_min.x, 0);
- point_min.y = MAX(point_min.y, 0);
- point_max.x = MIN(point_max.x, target->width);
- point_max.y = MIN(point_max.y, target->height);
- if (s_context.scissor_set) {
- point_min.x = MAX(point_min.x, s_context.scissor[0]);
- point_min.y = MAX(point_min.y, s_context.scissor[1]);
- point_max.x = MIN(point_max.x, s_context.scissor[2]);
- point_max.y = MIN(point_max.y, s_context.scissor[3]);
- }
- }
- Scale = 1.0f;
- Bias = 0.0f;
- new_matrix[0] = matrix->m[0][0] * Scale;
- new_matrix[1] = matrix->m[0][1] * Scale;
- new_matrix[2] = (matrix->m[0][0] + matrix->m[0][1]) * Bias + matrix->m[0][2];
- new_matrix[3] = matrix->m[1][0] * Scale;
- new_matrix[4] = matrix->m[1][1] * Scale;
- new_matrix[5] = (matrix->m[1][0] + matrix->m[1][1]) * Bias + matrix->m[1][2];
- /* Convert states into hardware values. */
- blend_mode = convert_blend(blend);
- format = convert_path_format(path->format);
- quality = convert_path_quality(path->quality);
- tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0;
- fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0;
- tessellation_size = s_context.tessbuf.tessbuf_size;
- /* Setup the command buffer. */
- /* Program color register. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, 0x01000002 | s_context.capabilities.cap.tiled | in_premult | image_mode | blend_mode | transparency_mode | s_context.enable_mask | s_context.color_transform | s_context.matrix_enable | s_context.scissor_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000400 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */
- /* Program matrix. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &new_matrix[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &new_matrix[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &new_matrix[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &new_matrix[3]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &new_matrix[4]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &new_matrix[5]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACD, (void *) &matrix->m[0][2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACE, (void *) &matrix->m[1][2]));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1)
- {
- if (path->path_changed != 0) {
- if (path->uploaded.handle != NULL) {
- free_memory.memory_handle = path->uploaded.handle;
- vg_lite_kernel(VG_LITE_FREE, &free_memory);
- path->uploaded.address = 0;
- path->uploaded.memory = NULL;
- path->uploaded.handle = NULL;
- }
- /* Allocate memory for the path data. */
- memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8);
- return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4;
- memory.contiguous = 1;
- VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory));
- ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0;
- ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8);
- ((uint32_t *) memory.memory)[1] = 0;
- memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length);
- ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN();
- ((uint32_t *) memory.memory)[return_offset + 1] = 0;
- path->uploaded.handle = memory.memory_handle;
- path->uploaded.memory = memory.memory;
- path->uploaded.address = memory.memory_gpu;
- path->uploaded.bytes = memory.bytes;
- path->path_changed = 0;
- }
- }
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- vglitemDUMP_BUFFER("path", (size_t)path->uploaded.address, (uint8_t *)(path->uploaded.memory), 0, path->uploaded.bytes);
- }
- #if !DUMP_COMMAND_CAPTURE
- vglitemDUMP("@[memory 0x%08X 0x%08X]", s_context.tessbuf.physical_addr, s_context.tessbuf.tessbuf_size);
- #endif
- if (width + point_min.x > target->width) {
- width = target->width - point_min.x;
- }
- #if (gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_512_PARALLEL_PATHS)
- {
- /* Tessellate path. */
- s_context.tessbuf.tess_w_h = width | (height << 16);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- } else {
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO)
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- }
- }
- #else
- {
- height = s_context.tessbuf.tess_w_h >> 16;
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) {
- #if gcFEATURE_VG_512_PARALLEL_PATHS
- if (height <= 128)
- parallel_workpaths1 = 4;
- else
- parallel_workpaths1 = height * 128 / 4096 - 1;
- if (parallel_workpaths1 > parallel_workpaths2)
- parallel_workpaths1 = parallel_workpaths2;
- #endif
- for (y = point_min.y; y < point_max.y; y += height) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16)));
- if (y + height > target->height) {
- temp_height = target->height - y;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (temp_height << 16)));
- }
- else {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (height << 16)));
- }
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- } else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- #if gcFEATURE_VG_512_PARALLEL_PATHS
- s_context.path_counter ++;
- if (parallel_workpaths1 == s_context.path_counter) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8)));
- s_context.path_counter = 0;
- }
- #endif
- }
- }
- }
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- for (y = point_min.y; y < point_max.y; y += height) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16)));
- if (y + height > target->height) {
- temp_height = target->height - y;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (temp_height << 16)));
- }
- else {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (height << 16)));
- }
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- } else {
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- #if gcFEATURE_VG_512_PARALLEL_PATHS
- s_context.path_counter ++;
- if (parallel_workpaths1 == s_context.path_counter) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8)));
- s_context.path_counter = 0;
- }
- #endif
- }
- }
- }
- }
- #endif
- /* Finialize command buffer. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0));
- #if gcFEATURE_VG_GLOBAL_ALPHA
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF));
- }
- #endif
- vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride)*(source->height));
- #if DUMP_IMAGE
- dump_img(source->memory, source->width, source->height, source->format);
- #endif
- return error;
- #else
- return VG_LITE_NOT_SUPPORT;
- #endif
- }
- /* GC555 vg_lite_draw_radial_grad API implementation
- */
- vg_lite_error_t vg_lite_draw_radial_grad(vg_lite_buffer_t* target,
- vg_lite_path_t* path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t* path_matrix,
- vg_lite_radial_gradient_t* grad,
- vg_lite_color_t paint_color,
- vg_lite_blend_t blend,
- vg_lite_filter_t filter)
- {
- #if DUMP_API
- FUNC_DUMP(vg_lite_draw_radial_grad)(target, path, fill_rule, path_matrix, grad, paint_color, blend, filter);
- #endif
- #if gcFEATURE_VG_RADIAL_GRADIENT && gcFEATURE_VG_IM_INPUT
- vg_lite_error_t error = VG_LITE_SUCCESS;
- uint32_t imageMode = 0;
- uint32_t blend_mode;
- uint32_t filter_mode = 0;
- uint32_t conversion = 0;
- uint32_t tiled_source;
- vg_lite_matrix_t inverse_matrix;
- vg_lite_float_t x_step[3];
- vg_lite_float_t y_step[3];
- vg_lite_float_t c_step[3];
- vg_lite_buffer_t* source = &grad->image;
- vg_lite_matrix_t* matrix = &grad->matrix;
- uint32_t rad_tile = 0;
- uint32_t transparency_mode = 0;
- uint32_t yuv2rgb = 0;
- uint32_t uv_swiz = 0;
- void* data;
- uint32_t compress_mode;
- uint32_t in_premult = 0;
- uint32_t src_premultiply_enable = 0;
- uint32_t premul_flag = 0;
- uint32_t prediv_flag = 0;
- /* The following code is from "draw path" */
- uint32_t format, quality, tiling, fill;
- uint32_t tessellation_size;
- vg_lite_kernel_allocate_t memory;
- vg_lite_kernel_free_t free_memory;
- uint32_t return_offset = 0;
- vg_lite_point_t point_min = { 0 }, point_max = { 0 }, temp = { 0 };
- int width, height;
- uint8_t ts_is_fullscreen = 0;
- float new_matrix[6];
- float Scale, Bias;
- vg_lite_float_t radius;
- vg_lite_float_t centerX, centerY;
- vg_lite_float_t focalX, focalY;
- vg_lite_float_t fx, fy;
- vg_lite_float_t fxfy_2;
- vg_lite_float_t radius2;
- vg_lite_float_t r2_fx2, r2_fy2;
- vg_lite_float_t r2_fx2_2, r2_fy2_2;
- vg_lite_float_t r2_fx2_fy2;
- vg_lite_float_t r2_fx2_fy2sq;
- vg_lite_float_t cx, cy;
- vg_lite_float_t rgConstantLin, rgStepXLin, rgStepYLin;
- vg_lite_float_t rgConstantRad, rgStepXRad, rgStepYRad;
- vg_lite_float_t rgStepXXRad, rgStepYYRad, rgStepXYRad;
- int y;
- int temp_height = 0;
- #if !gcFEATURE_VG_PARALLEL_PATHS
- uint32_t parallel_workpaths1 = 2;
- uint32_t parallel_workpaths2 = 2;
- #endif
- #if gcFEATURE_VG_TRACE_API
- VGLITE_LOG("vg_lite_draw_radial_grad %p %p %d %p %p 0x%08X %d %d\n",
- target, path, fill_rule, path_matrix, grad, paint_color, blend, filter);
- #endif
- #if gcFEATURE_VG_ERROR_CHECK
- #if !gcFEATURE_VG_QUALITY_8X
- if (path->quality == VG_LITE_UPPER) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_LVGL_SUPPORT
- if ((blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL)) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_24BIT
- if (target->format >= VG_LITE_RGB888 && target->format <= VG_LITE_RGBA5658) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_STENCIL
- if (source->image_mode == VG_LITE_STENCIL_MODE) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_NEW_BLEND_MODE
- if (blend == VG_LITE_BLEND_DARKEN || blend == VG_LITE_BLEND_LIGHTEN) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- #if !gcFEATURE_VG_IM_REPEAT_REFLECT
- if (grad->spread_mode == VG_LITE_GRADIENT_SPREAD_REPEAT || grad->spread_mode == VG_LITE_GRADIENT_SPREAD_REFLECT) {
- return VG_LITE_NOT_SUPPORT;
- }
- #endif
- if (source->format == VG_LITE_A4 || source->format == VG_LITE_A8) {
- return VG_LITE_NOT_SUPPORT;
- }
- if (!path || !path->path) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- radius = grad->radial_grad.r;
- if (radius < 0) {
- return VG_LITE_INVALID_ARGUMENT;
- }
- VG_LITE_RETURN_ERROR(check_compress(source->format, source->compress_mode, source->tiled, source->width, source->height));
- #endif /* gcFEATURE_VG_ERROR_CHECK */
- if (!path->path_length) {
- return VG_LITE_SUCCESS;
- }
- if (!path_matrix) {
- path_matrix = &identity_mtx;
- }
- #if gcFEATURE_VG_GAMMA
- set_gamma_dest_only(target, VGL_TRUE);
- #endif
- #if gcFEATURE_VG_GLOBAL_ALPHA
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_GLOBAL, 0xff));
- }
- #endif
- /*blend input into context*/
- s_context.blend_mode = blend;
- src_premultiply_enable = 0x01000100;
- if (s_context.color_transform == 0 && s_context.gamma_dst == s_context.gamma_src && s_context.matrix_enable == 0 && s_context.dst_alpha_mode == 0 && s_context.src_alpha_mode == 0 &&
- (source->image_mode == VG_LITE_NORMAL_IMAGE_MODE || source->image_mode == 0)) {
- prediv_flag = 0;
- }
- else {
- prediv_flag = 1;
- }
- if ((s_context.blend_mode >= OPENVG_BLEND_SRC_OVER && s_context.blend_mode <= OPENVG_BLEND_ADDITIVE) || source->image_mode == VG_LITE_STENCIL_MODE
- || (s_context.blend_mode >= VG_LITE_BLEND_NORMAL_LVGL && s_context.blend_mode <= VG_LITE_BLEND_MULTIPLY_LVGL)) {
- premul_flag = 1;
- }
- else {
- premul_flag = 0;
- }
- if ((source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 0) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 0)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x10000000;
- }
- /* when src and dst all pre format, im pre_out set to 0 to perform data truncation to prevent data overflow */
- else if (source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 0) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 0 && target->premultiplied == 1) ||
- (source->premultiplied == 0 && target->premultiplied == 0 && premul_flag == 1)) {
- src_premultiply_enable = 0x01000100;
- in_premult = 0x00000000;
- }
- else if ((source->premultiplied == 1 && target->premultiplied == 1 && prediv_flag == 1) ||
- (source->premultiplied == 1 && target->premultiplied == 0 && prediv_flag == 1)) {
- src_premultiply_enable = 0x00000100;
- in_premult = 0x00000000;
- }
- if ((source->format == VG_LITE_A4 || source->format == VG_LITE_A8) && blend >= VG_LITE_BLEND_SRC_OVER && blend <= VG_LITE_BLEND_SUBTRACT) {
- #if (CHIPID==0x255)
- src_premultiply_enable = 0x00000000;
- #endif
- in_premult = 0x00000000;
- }
- if (source->premultiplied == target->premultiplied && premul_flag == 0) {
- target->apply_premult = 1;
- }
- else {
- target->apply_premult = 0;
- }
- error = set_render_target(target);
- if (error != VG_LITE_SUCCESS) {
- return error;
- } else if (error == VG_LITE_NO_CONTEXT) {
- /* If scissoring is enabled and no valid scissoring rectangles
- are present, no drawing occurs */
- return VG_LITE_SUCCESS;
- }
- if ((target->format == VG_LITE_YUYV || target->format == VG_LITE_YUY2 || target->format == VG_LITE_YUY2_TILED
- || target->format == VG_LITE_AYUY2 || target->format == VG_LITE_AYUY2_TILED)
- && path->quality != VG_LITE_LOW)
- {
- path->quality = VG_LITE_LOW;
- printf("If target is YUV group , the path qulity should use VG_LITE_LOW.\n");
- }
- transparency_mode = (source->transparency_mode == VG_LITE_IMAGE_TRANSPARENT ? 0x8000:0);
- width = s_context.tessbuf.tess_w_h & 0xFFFF;
- height = s_context.tessbuf.tess_w_h >> 16;
- if (width == 0 || height == 0)
- return VG_LITE_NO_CONTEXT;
- if ((target->width <= width) && (target->height <= height) && (!s_context.scissor_set))
- {
- ts_is_fullscreen = 1;
- point_min.x = 0;
- point_min.y = 0;
- point_max.x = target->width;
- point_max.y = target->height;
- }
- /* If target is L8 and source is in YUV or RGB (not L8 or A8) then we have to convert RGB into L8. */
- if ((target->format == VG_LITE_L8) && ((source->format != VG_LITE_L8) && (source->format != VG_LITE_A8))) {
- conversion = 0x80000000;
- }
- /* Determine image mode (NORMAL, NONE , MULTIPLY or STENCIL) depending on the color. */
- switch (source->image_mode) {
- case VG_LITE_NONE_IMAGE_MODE:
- imageMode = 0x0;
- break;
- case VG_LITE_MULTIPLY_IMAGE_MODE:
- return VG_LITE_INVALID_ARGUMENT;
- case VG_LITE_NORMAL_IMAGE_MODE:
- case VG_LITE_ZERO:
- imageMode = 0x00001000;
- break;
- case VG_LITE_STENCIL_MODE:
- imageMode = 0x00003000;
- break;
- case VG_LITE_RECOLOR_MODE:
- imageMode = 0x00006000;
- break;
- }
- switch (filter) {
- case VG_LITE_FILTER_POINT:
- filter_mode = 0;
- break;
- case VG_LITE_FILTER_LINEAR:
- filter_mode = 0x10000;
- break;
- case VG_LITE_FILTER_BI_LINEAR:
- filter_mode = 0x20000;
- break;
- case VG_LITE_FILTER_GAUSSIAN:
- filter_mode = 0x30000;
- break;
- }
- tiled_source = (source->tiled != VG_LITE_LINEAR) ? 0x10000000 : 0 ;
- switch (grad->spread_mode) {
- case VG_LITE_GRADIENT_SPREAD_FILL:
- rad_tile = 0x0;
- break;
- case VG_LITE_GRADIENT_SPREAD_PAD:
- rad_tile = 0x1000;
- break;
- case VG_LITE_GRADIENT_SPREAD_REPEAT:
- rad_tile = 0x2000;
- break;
- case VG_LITE_GRADIENT_SPREAD_REFLECT:
- rad_tile = 0x3000;
- break;
- }
- compress_mode = (uint32_t)source->compress_mode << 25;
- if (grad->spread_mode == VG_LITE_GRADIENT_SPREAD_FILL)
- {
- uint8_t a,r,g,b;
- a = paint_color >> 24;
- r = paint_color >> 16;
- g = paint_color >> 8;
- b = paint_color;
- paint_color = (a << 24) | (b << 16) | (g << 8) | r;
- }
- /* compute radial gradient paremeters */
- /* Compute inverse matrix. */
- if (!inverse(&inverse_matrix, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- /* Make shortcuts to the gradient information. */
- centerX = grad->radial_grad.cx;
- centerY = grad->radial_grad.cy;
- focalX = grad->radial_grad.fx;
- focalY = grad->radial_grad.fy;
- /* Compute constants of the equation. */
- fx = focalX - centerX;
- fy = focalY - centerY;
- radius2 = radius * radius;
- if (fx*fx + fy*fy > radius2)
- {
- /* If the focal point is outside the circle, let's move it
- to inside the circle. Per vg11 spec pg125 "If (fx, fy) lies outside ...
- For here, we set it at 0.9 ratio to the center.
- */
- vg_lite_float_t fr = (vg_lite_float_t)sqrt(fx*fx + fy*fy);
- fx = radius * fx / fr * 0.9f;
- fy = radius * fy / fr * 0.9f;
- focalX = grad->radial_grad.fx + fx;
- focalY = grad->radial_grad.fy + fy;
- }
- fxfy_2 = 2.0f * fx * fy;
- r2_fx2 = radius2 - fx * fx;
- r2_fy2 = radius2 - fy * fy;
- r2_fx2_2 = 2.0f * r2_fx2;
- r2_fy2_2 = 2.0f * r2_fy2;
- #if gcFEATURE_VG_MATH_PRECISION_FIX
- r2_fx2_fy2 = (r2_fx2 - fy * fy) / source->width;
- r2_fx2_fy2sq = (r2_fx2_fy2 * r2_fx2_fy2);
- #else
- r2_fx2_fy2 = r2_fx2 - fy * fy;
- r2_fx2_fy2sq = r2_fx2_fy2 * r2_fx2_fy2;
- #endif
- /* _____________________________________
- ** dx fx + dy fy + \/r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2
- ** g = -------------------------------------------------------
- ** r^2 - fx^2 - fy^2
- **
- ** Where
- **
- ** dx := F(x) - focalX
- ** dy := F(y) - focalY
- ** fx := focalX - centerX
- ** fy := focalX - centerY
- **
- ** and
- **
- ** F(x) := (x + 0.5) m00 + (y + 0.5) m01 + m02
- ** F(y) := (x + 0.5) m10 + (y + 0.5) m11 + m12
- **
- ** So, dx can be factored into
- **
- ** dx = (x + 0.5) m00 + (y + 0.5) m01 + m02 - focalX
- ** = x m00 + y m01 + 0.5 m00 + 0.5 m01 + m02 - focalX
- **
- ** = x m00 + y m01 + cx
- **
- ** where
- **
- ** cx := 0.5 m00 + 0.5 m01 + m02 - focalX
- **
- ** The same way we can factor dy into
- **
- ** dy = x m10 + y m11 + cy
- **
- ** where
- **
- ** cy := 0.5 m10 + 0.5 m11 + m12 - focalY.
- **
- ** Now we can rewrite g as
- ** ______________________________________
- ** dx fx + dy fy / r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2
- ** g = ----------------- + \ / -------------------------------------
- ** r^2 - fx^2 - fy^2 \/ (r^2 - fx^2 - fy^2)^2
- ** ____
- ** = gLin + \/gRad
- **
- ** where
- **
- ** dx fx + dy fy
- ** gLin := -----------------
- ** r^2 - fx^2 - fy^2
- **
- ** r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2
- ** gRad := -------------------------------------
- ** (r^2 - fx^2 - fy^2)^2
- */
- cx
- = 0.5f * ( MAT(&inverse_matrix, 0, 0) + MAT(&inverse_matrix, 0, 1) )
- + MAT(&inverse_matrix, 0, 2)
- - focalX;
- cy
- = 0.5f * ( MAT(&inverse_matrix, 1, 0) + MAT(&inverse_matrix, 1, 1) )
- + MAT(&inverse_matrix, 1, 2)
- - focalY;
- /*
- ** dx fx + dy fy
- ** gLin := -----------------
- ** r^2 - fx^2 - fy^2
- **
- ** We can factor the top half into
- **
- ** = (x m00 + y m01 + cx) fx + (x m10 + y m11 + cy) fy
- **
- ** = x (m00 fx + m10 fy)
- ** + y (m01 fx + m11 fy)
- ** + cx fx + cy fy.
- */
- rgStepXLin
- = ( MAT(&inverse_matrix, 0, 0) * fx + MAT(&inverse_matrix, 1, 0) * fy )
- / r2_fx2_fy2;
- rgStepYLin
- = ( MAT(&inverse_matrix, 0, 1) * fx + MAT(&inverse_matrix, 1, 1) * fy )
- / r2_fx2_fy2;
- rgConstantLin = ( cx * fx + cy * fy ) / r2_fx2_fy2;
- /*
- ** r^2 (dx^2 + dy^2) - (dx fy - dy fx)^2
- ** gRad := -------------------------------------
- ** (r^2 - fx^2 - fy^2)^2
- **
- ** r^2 (dx^2 + dy^2) - dx^2 fy^2 - dy^2 fx^2 + 2 dx dy fx fy
- ** := ---------------------------------------------------------
- ** (r^2 - fx^2 - fy^2)^2
- **
- ** dx^2 (r^2 - fy^2) + dy^2 (r^2 - fx^2) + 2 dx dy fx fy
- ** := -----------------------------------------------------
- ** (r^2 - fx^2 - fy^2)^2
- **
- ** First, lets factor dx^2 into
- **
- ** dx^2 = (x m00 + y m01 + cx)^2
- ** = x^2 m00^2 + y^2 m01^2 + 2 x y m00 m01
- ** + 2 x m00 cx + 2 y m01 cx + cx^2
- **
- ** = x^2 (m00^2)
- ** + y^2 (m01^2)
- ** + x y (2 m00 m01)
- ** + x (2 m00 cx)
- ** + y (2 m01 cx)
- ** + cx^2.
- **
- ** The same can be done for dy^2:
- **
- ** dy^2 = x^2 (m10^2)
- ** + y^2 (m11^2)
- ** + x y (2 m10 m11)
- ** + x (2 m10 cy)
- ** + y (2 m11 cy)
- ** + cy^2.
- **
- ** Let's also factor dx dy into
- **
- ** dx dy = (x m00 + y m01 + cx) (x m10 + y m11 + cy)
- ** = x^2 m00 m10 + y^2 m01 m11 + x y m00 m11 + x y m01 m10
- ** + x m00 cy + x m10 cx + y m01 cy + y m11 cx + cx cy
- **
- ** = x^2 (m00 m10)
- ** + y^2 (m01 m11)
- ** + x y (m00 m11 + m01 m10)
- ** + x (m00 cy + m10 cx)
- ** + y (m01 cy + m11 cx)
- ** + cx cy.
- **
- ** Now that we have all this, lets look at the top of gRad.
- **
- ** = dx^2 (r^2 - fy^2) + dy^2 (r^2 - fx^2) + 2 dx dy fx fy
- ** = x^2 m00^2 (r^2 - fy^2) + y^2 m01^2 (r^2 - fy^2)
- ** + x y 2 m00 m01 (r^2 - fy^2) + x 2 m00 cx (r^2 - fy^2)
- ** + y 2 m01 cx (r^2 - fy^2) + cx^2 (r^2 - fy^2)
- ** + x^2 m10^2 (r^2 - fx^2) + y^2 m11^2 (r^2 - fx^2)
- ** + x y 2 m10 m11 (r^2 - fx^2) + x 2 m10 cy (r^2 - fx^2)
- ** + y 2 m11 cy (r^2 - fx^2) + cy^2 (r^2 - fx^2)
- ** + x^2 m00 m10 2 fx fy + y^2 m01 m11 2 fx fy
- ** + x y (m00 m11 + m01 m10) 2 fx fy
- ** + x (m00 cy + m10 cx) 2 fx fy + y (m01 cy + m11 cx) 2 fx fy
- ** + cx cy 2 fx fy
- **
- ** = x^2 ( m00^2 (r^2 - fy^2)
- ** + m10^2 (r^2 - fx^2)
- ** + m00 m10 2 fx fy
- ** )
- ** + y^2 ( m01^2 (r^2 - fy^2)
- ** + m11^2 (r^2 - fx^2)
- ** + m01 m11 2 fx fy
- ** )
- ** + x y ( 2 m00 m01 (r^2 - fy^2)
- ** + 2 m10 m11 (r^2 - fx^2)
- ** + (m00 m11 + m01 m10) 2 fx fy
- ** )
- ** + x ( 2 m00 cx (r^2 - fy^2)
- ** + 2 m10 cy (r^2 - fx^2)
- ** + (m00 cy + m10 cx) 2 fx fy
- ** )
- ** + y ( 2 m01 cx (r^2 - fy^2)
- ** + 2 m11 cy (r^2 - fx^2)
- ** + (m01 cy + m11 cx) 2 fx fy
- ** )
- ** + cx^2 (r^2 - fy^2) + cy^2 (r^2 - fx^2) + cx cy 2 fx fy.
- */
- rgStepXXRad =
- (
- MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 0, 0) * r2_fy2
- + MAT(&inverse_matrix, 1, 0) * MAT(&inverse_matrix, 1, 0) * r2_fx2
- + MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 1, 0) * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgStepYYRad =
- (
- MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 0, 1) * r2_fy2
- + MAT(&inverse_matrix, 1, 1) * MAT(&inverse_matrix, 1, 1) * r2_fx2
- + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 1, 1) * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgStepXYRad =
- (
- MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 0, 1) * r2_fy2_2
- + MAT(&inverse_matrix, 1, 0) * MAT(&inverse_matrix, 1, 1) * r2_fx2_2
- + (
- MAT(&inverse_matrix, 0, 0) * MAT(&inverse_matrix, 1, 1)
- + MAT(&inverse_matrix, 0, 1) * MAT(&inverse_matrix, 1, 0)
- )
- * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgStepXRad =
- (
- MAT(&inverse_matrix, 0, 0) * cx * r2_fy2_2
- + MAT(&inverse_matrix, 1, 0) * cy * r2_fx2_2
- + (
- MAT(&inverse_matrix, 0, 0) * cy
- + MAT(&inverse_matrix, 1, 0) * cx
- )
- * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgStepYRad =
- (
- MAT(&inverse_matrix, 0, 1) * cx * r2_fy2_2
- + MAT(&inverse_matrix, 1, 1) * cy * r2_fx2_2
- + (
- MAT(&inverse_matrix, 0, 1) * cy
- + MAT(&inverse_matrix, 1, 1) * cx
- )
- * fxfy_2
- )
- / r2_fx2_fy2sq;
- rgConstantRad =
- (
- cx * cx * r2_fy2
- + cy * cy * r2_fx2
- + cx * cy * fxfy_2
- )
- / r2_fx2_fy2sq;
- /* Setup the command buffer. */
- /* rad gradient parameters*/
- data = &rgConstantLin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A04,*(uint32_t*) data));
- data = &rgStepXLin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A06,*(uint32_t*) data));
- data = &rgStepYLin;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A08,*(uint32_t*) data));
- data = &rgConstantRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A05,*(uint32_t*) data));
- data = &rgStepXRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A07,*(uint32_t*) data));
- data = &rgStepYRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A09,*(uint32_t*) data));
- data = &rgStepXXRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A03,*(uint32_t*) data));
- data = &rgStepYYRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0A,*(uint32_t*) data));
- data = &rgStepXYRad;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A0B,*(uint32_t*) data));
- /* Compute inverse matrix. */
- if (!inverse(&inverse_matrix, matrix))
- return VG_LITE_INVALID_ARGUMENT;
- #if gcFEATURE_VG_MATH_PRECISION_FIX
- /* Compute interpolation steps. */
- x_step[0] = inverse_matrix.m[0][0];
- x_step[1] = inverse_matrix.m[1][0];
- x_step[2] = inverse_matrix.m[2][0];
- y_step[0] = inverse_matrix.m[0][1];
- y_step[1] = inverse_matrix.m[1][1];
- y_step[2] = inverse_matrix.m[2][1];
- c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]);
- c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]);
- c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2];
- #else
- /* Compute interpolation steps. */
- x_step[0] = inverse_matrix.m[0][0] / source->width;
- x_step[1] = inverse_matrix.m[1][0] / source->height;
- x_step[2] = inverse_matrix.m[2][0];
- y_step[0] = inverse_matrix.m[0][1] / source->width;
- y_step[1] = inverse_matrix.m[1][1] / source->height;
- y_step[2] = inverse_matrix.m[2][1];
- c_step[0] = (0.5f * (inverse_matrix.m[0][0] + inverse_matrix.m[0][1]) + inverse_matrix.m[0][2]) / source->width;
- c_step[1] = (0.5f * (inverse_matrix.m[1][0] + inverse_matrix.m[1][1]) + inverse_matrix.m[1][2]) / source->height;
- c_step[2] = 0.5f * (inverse_matrix.m[2][0] + inverse_matrix.m[2][1]) + inverse_matrix.m[2][2];
- #endif
- /* Setup the command buffer. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A18, (void *) &c_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A19, (void *) &c_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1A, (void *) &c_step[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1C, (void *) &x_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1D, (void *) &x_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A1E, (void *) &x_step[2]));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1F, 0x00000001));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A20, (void *) &y_step[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A21, (void *) &y_step[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A22, (void *) &y_step[2]));
- if (((source->format >= VG_LITE_YUY2) &&
- (source->format <= VG_LITE_AYUY2)) ||
- ((source->format >= VG_LITE_YUY2_TILED) &&
- (source->format <= VG_LITE_AYUY2_TILED))) {
- yuv2rgb = convert_yuv2rgb(source->yuv.yuv2rgb);
- uv_swiz = convert_uv_swizzle(source->yuv.swizzle);
- }
- if (source->yuv.uv_planar) {
- /* Program u plane address if necessary. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A51, source->yuv.uv_planar));
- }
- if (source->yuv.v_planar) {
- /* Program v plane address if necessary. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A53, source->yuv.v_planar));
- }
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A24, convert_source_format(source->format) |
- filter_mode | uv_swiz | yuv2rgb | rad_tile | conversion | src_premultiply_enable | compress_mode));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A26, paint_color));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A28, source->address));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2A, tiled_source));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2C, 0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A2E, source->width | (source->height << 16)));
- /* Work on path states. */
- matrix = path_matrix;
- if (ts_is_fullscreen == 0) {
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[1], matrix);
- point_min = point_max = temp;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[1], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[2], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- transform(&temp, (vg_lite_float_t)path->bounding_box[0], (vg_lite_float_t)path->bounding_box[3], matrix);
- if (temp.x < point_min.x) point_min.x = temp.x;
- if (temp.y < point_min.y) point_min.y = temp.y;
- if (temp.x > point_max.x) point_max.x = temp.x;
- if (temp.y > point_max.y) point_max.y = temp.y;
- point_min.x = MAX(point_min.x, 0);
- point_min.y = MAX(point_min.y, 0);
- point_max.x = MIN(point_max.x, target->width);
- point_max.y = MIN(point_max.y, target->height);
- if (s_context.scissor_set) {
- point_min.x = MAX(point_min.x, s_context.scissor[0]);
- point_min.y = MAX(point_min.y, s_context.scissor[1]);
- point_max.x = MIN(point_max.x, s_context.scissor[2]);
- point_max.y = MIN(point_max.y, s_context.scissor[3]);
- }
- }
- Scale = 1.0f;
- Bias = 0.0f;
- new_matrix[0] = matrix->m[0][0] * Scale;
- new_matrix[1] = matrix->m[0][1] * Scale;
- new_matrix[2] = (matrix->m[0][0] + matrix->m[0][1]) * Bias + matrix->m[0][2];
- new_matrix[3] = matrix->m[1][0] * Scale;
- new_matrix[4] = matrix->m[1][1] * Scale;
- new_matrix[5] = (matrix->m[1][0] + matrix->m[1][1]) * Bias + matrix->m[1][2];
- /* Convert states into hardware values. */
- blend_mode = convert_blend(blend);
- format = convert_path_format(path->format);
- quality = convert_path_quality(path->quality);
- tiling = (s_context.capabilities.cap.tiled == 2) ? 0x2000000 : 0;
- fill = (fill_rule == VG_LITE_FILL_EVEN_ODD) ? 0x10 : 0;
- tessellation_size = s_context.tessbuf.tessbuf_size;
- /* Setup the command buffer. */
- /* Program color register. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A00, 0x02000002 | s_context.capabilities.cap.tiled | in_premult | imageMode | blend_mode | transparency_mode | s_context.enable_mask | s_context.color_transform | s_context.matrix_enable | s_context.scissor_enable));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000000 | format | quality | tiling | fill));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3B, 0x3F800000)); /* Path tessellation SCALE. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3C, 0x00000000)); /* Path tessellation BIAS. */
- /* Program matrix. */
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A40, (void *) &new_matrix[0]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A41, (void *) &new_matrix[1]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A42, (void *) &new_matrix[2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A43, (void *) &new_matrix[3]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A44, (void *) &new_matrix[4]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0A45, (void *) &new_matrix[5]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACD, (void *) &matrix->m[0][2]));
- VG_LITE_RETURN_ERROR(push_state_ptr(&s_context, 0x0ACE, (void *) &matrix->m[1][2]));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1)
- {
- if (path->path_changed != 0) {
- if (path->uploaded.handle != NULL) {
- free_memory.memory_handle = path->uploaded.handle;
- vg_lite_kernel(VG_LITE_FREE, &free_memory);
- path->uploaded.address = 0;
- path->uploaded.memory = NULL;
- path->uploaded.handle = NULL;
- }
- /* Allocate memory for the path data. */
- memory.bytes = 16 + VG_LITE_ALIGN(path->path_length, 8);
- return_offset = (8 + VG_LITE_ALIGN(path->path_length, 8)) / 4;
- memory.contiguous = 1;
- VG_LITE_RETURN_ERROR(vg_lite_kernel(VG_LITE_ALLOCATE, &memory));
- ((uint64_t *) memory.memory)[(path->path_length + 7) / 8] = 0;
- ((uint32_t *) memory.memory)[0] = VG_LITE_DATA((path->path_length + 7) / 8);
- ((uint32_t *) memory.memory)[1] = 0;
- memcpy((uint8_t *) memory.memory + 8, path->path, path->path_length);
- ((uint32_t *) memory.memory)[return_offset] = VG_LITE_RETURN();
- ((uint32_t *) memory.memory)[return_offset + 1] = 0;
- path->uploaded.handle = memory.memory_handle;
- path->uploaded.memory = memory.memory;
- path->uploaded.address = memory.memory_gpu;
- path->uploaded.bytes = memory.bytes;
- path->path_changed = 0;
- }
- }
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- vglitemDUMP_BUFFER("path", (size_t)path->uploaded.address, (uint8_t *)(path->uploaded.memory), 0, path->uploaded.bytes);
- }
- #if !DUMP_COMMAND_CAPTURE
- vglitemDUMP("@[memory 0x%08X 0x%08X]", s_context.tessbuf.physical_addr, s_context.tessbuf.tessbuf_size);
- #endif
- if (width + point_min.x > target->width) {
- width = target->width - point_min.x;
- }
- #if (gcFEATURE_VG_PARALLEL_PATHS && gcFEATURE_VG_512_PARALLEL_PATHS)
- {
- /* Tessellate path. */
- s_context.tessbuf.tess_w_h = width | (height << 16);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (point_min.y << 16)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, s_context.tessbuf.tess_w_h));
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- } else {
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO)
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- }
- }
- }
- #else
- {
- height = s_context.tessbuf.tess_w_h >> 16;
- if (path->path_type == VG_LITE_DRAW_FILL_PATH || path->path_type == VG_LITE_DRAW_ZERO) {
- #if gcFEATURE_VG_512_PARALLEL_PATHS
- if (height <= 128)
- parallel_workpaths1 = 4;
- else
- parallel_workpaths1 = height * 128 / 4096 - 1;
- if (parallel_workpaths1 > parallel_workpaths2)
- parallel_workpaths1 = parallel_workpaths2;
- #endif
- for (y = point_min.y; y < point_max.y; y += height) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16)));
- if (y + height > target->height) {
- temp_height = target->height - y;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (temp_height << 16)));
- }
- else {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (height << 16)));
- }
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- } else {
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->path_length, path->path));
- #if gcFEATURE_VG_512_PARALLEL_PATHS
- s_context.path_counter ++;
- if (parallel_workpaths1 == s_context.path_counter) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8)));
- s_context.path_counter = 0;
- }
- #endif
- }
- }
- }
- if (path->path_type == VG_LITE_DRAW_STROKE_PATH || path->path_type == VG_LITE_DRAW_FILL_STROKE_PATH) {
- for (y = point_min.y; y < point_max.y; y += height) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A1B, 0x00011000));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3D, tessellation_size / 64));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A39, point_min.x | (y << 16)));
- if (y + height > target->height) {
- temp_height = target->height - y;
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (temp_height << 16)));
- }
- else {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A3A, width | (height << 16)));
- }
- if (VLM_PATH_GET_UPLOAD_BIT(*path) == 1) {
- VG_LITE_RETURN_ERROR(push_call(&s_context, path->uploaded.address, path->uploaded.bytes));
- } else {
- format = convert_path_format(VG_LITE_FP32);
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0x01000200 | format | quality | tiling | 0x0));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A02, path->stroke_color));
- VG_LITE_RETURN_ERROR(push_data(&s_context, path->stroke_size, path->stroke_path));
- #if gcFEATURE_VG_512_PARALLEL_PATHS
- s_context.path_counter ++;
- if (parallel_workpaths1 == s_context.path_counter) {
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0E02, 0x10 | (0x7 << 8)));
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0F00, 0x10 | (0x7 << 8)));
- s_context.path_counter = 0;
- }
- #endif
- }
- }
- }
- }
- #endif
- /* Finialize command buffer. */
- VG_LITE_RETURN_ERROR(push_state(&s_context, 0x0A34, 0));
- #if gcFEATURE_VG_GLOBAL_ALPHA
- if (blend >= VG_LITE_BLEND_NORMAL_LVGL && blend <= VG_LITE_BLEND_MULTIPLY_LVGL) {
- VG_LITE_RETURN_ERROR(vg_lite_dest_global_alpha(VG_LITE_NORMAL, 0xFF));
- }
- #endif
- vglitemDUMP_BUFFER("image", (size_t)source->address, source->memory, 0, (source->stride)*(source->height));
- #if DUMP_IMAGE
- dump_img(source->memory, source->width, source->height, source->format);
- #endif
- return error;
- #else
- return VG_LITE_NOT_SUPPORT;
- #endif
- }
- #endif /* (CHIPID==0x355 || CHIPID==0x255) */
- /* GC555/GC355/GC255 vg_lite_draw_grad API implementation
- */
- vg_lite_error_t vg_lite_draw_grad(vg_lite_buffer_t* target,
- vg_lite_path_t* path,
- vg_lite_fill_t fill_rule,
- vg_lite_matrix_t* matrix,
- vg_lite_linear_gradient_t* grad,
- vg_lite_blend_t blend)
- {
- #if DUMP_API
- FUNC_DUMP(vg_lite_draw_grad)(target, path, fill_rule, matrix, grad, blend);
- #endif
- return vg_lite_draw_pattern(target, path, fill_rule, matrix,
- &grad->image, &grad->matrix, blend, VG_LITE_PATTERN_PAD, 0, 0, VG_LITE_FILTER_LINEAR);
- }
|